├── .dockerignore ├── .github ├── dependabot.yml └── workflows │ ├── ci.yml │ ├── codacy.yml │ └── docker.yml ├── .gitignore ├── .golangci.yml ├── Dockerfile ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── bench ├── README.md ├── cpp │ ├── CMakeLists.txt │ ├── scan_test.cpp │ └── scan_test.h.in └── go │ ├── chimera_test.go │ └── scan_test.go ├── chimera ├── api.go ├── api_test.go ├── block.go ├── common.go ├── common_test.go ├── common_v54.go ├── compile.go ├── compile_test.go ├── doc.go ├── example_api_test.go ├── example_compile_test.go ├── example_runtime_test.go ├── pattern.go ├── pattern_test.go ├── runtime.go ├── runtime_test.go └── scratch.go ├── docker-compose.yml ├── examples ├── pcapscan │ ├── main.go │ └── patterns └── simplegrep │ └── main.go ├── go.mod ├── go.sum ├── hyperscan ├── api.go ├── api_test.go ├── block.go ├── common.go ├── common_test.go ├── compile.go ├── compile_test.go ├── compile_v5.go ├── compile_v5_test.go ├── doc.go ├── example_api_test.go ├── example_compile_test.go ├── example_runtime_test.go ├── literal_v52.go ├── literal_v52_test.go ├── pattern.go ├── pattern_test.go ├── patterns.go ├── patterns_test.go ├── platform.go ├── platform_test.go ├── platform_v54.go ├── runtime.go ├── runtime_test.go ├── scratch.go ├── stream.go └── vectored.go ├── internal ├── ch │ ├── allocator.go │ ├── allocator_test.go │ ├── common.go │ ├── common_test.go │ ├── compile.go │ ├── compile_test.go │ ├── dummy.cxx │ ├── error.go │ ├── error_v54.go │ ├── link.go │ ├── runtime.go │ ├── runtime_test.go │ ├── scratch.go │ └── scratch_test.go ├── handle │ └── handle.go └── hs │ ├── allocator.go │ ├── allocator_test.go │ ├── common.go │ ├── common_test.go │ ├── compile.go │ ├── compile_test.go │ ├── compile_v5.go │ ├── compile_v52.go │ ├── compile_v54.go │ ├── dummy.cxx │ ├── error.go │ ├── error_v5.go │ ├── link.go │ ├── runtime.go │ ├── runtime_test.go │ ├── scratch.go │ ├── scratch_test.go │ ├── stream.go │ └── stream_test.go └── vendor ├── github.com ├── google │ └── gopacket │ │ ├── .gitignore │ │ ├── .travis.gofmt.sh │ │ ├── .travis.golint.sh │ │ ├── .travis.govet.sh │ │ ├── .travis.install.sh │ │ ├── .travis.script.sh │ │ ├── .travis.yml │ │ ├── AUTHORS │ │ ├── CONTRIBUTING.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── base.go │ │ ├── decode.go │ │ ├── doc.go │ │ ├── flows.go │ │ ├── gc │ │ ├── layerclass.go │ │ ├── layers │ │ ├── .lint_blacklist │ │ ├── arp.go │ │ ├── asf.go │ │ ├── asf_presencepong.go │ │ ├── base.go │ │ ├── bfd.go │ │ ├── cdp.go │ │ ├── ctp.go │ │ ├── dhcpv4.go │ │ ├── dhcpv6.go │ │ ├── dhcpv6_options.go │ │ ├── dns.go │ │ ├── doc.go │ │ ├── dot11.go │ │ ├── dot1q.go │ │ ├── eap.go │ │ ├── eapol.go │ │ ├── endpoints.go │ │ ├── enums.go │ │ ├── enums_generated.go │ │ ├── erspan2.go │ │ ├── etherip.go │ │ ├── ethernet.go │ │ ├── fddi.go │ │ ├── fuzz_layer.go │ │ ├── gen_linted.sh │ │ ├── geneve.go │ │ ├── gre.go │ │ ├── gtp.go │ │ ├── iana_ports.go │ │ ├── icmp4.go │ │ ├── icmp6.go │ │ ├── icmp6msg.go │ │ ├── igmp.go │ │ ├── ip4.go │ │ ├── ip6.go │ │ ├── ipsec.go │ │ ├── layertypes.go │ │ ├── lcm.go │ │ ├── linux_sll.go │ │ ├── llc.go │ │ ├── lldp.go │ │ ├── loopback.go │ │ ├── mldv1.go │ │ ├── mldv2.go │ │ ├── modbustcp.go │ │ ├── mpls.go │ │ ├── ndp.go │ │ ├── ntp.go │ │ ├── ospf.go │ │ ├── pflog.go │ │ ├── ports.go │ │ ├── ppp.go │ │ ├── pppoe.go │ │ ├── prism.go │ │ ├── radiotap.go │ │ ├── radius.go │ │ ├── rmcp.go │ │ ├── rudp.go │ │ ├── sctp.go │ │ ├── sflow.go │ │ ├── sip.go │ │ ├── stp.go │ │ ├── tcp.go │ │ ├── tcpip.go │ │ ├── test_creator.py │ │ ├── tls.go │ │ ├── tls_alert.go │ │ ├── tls_appdata.go │ │ ├── tls_cipherspec.go │ │ ├── tls_handshake.go │ │ ├── udp.go │ │ ├── udplite.go │ │ ├── usb.go │ │ ├── vrrp.go │ │ └── vxlan.go │ │ ├── layers_decoder.go │ │ ├── layertype.go │ │ ├── packet.go │ │ ├── parser.go │ │ ├── pcap │ │ ├── defs_windows_386.go │ │ ├── defs_windows_amd64.go │ │ ├── doc.go │ │ ├── pcap.go │ │ ├── pcap_unix.go │ │ ├── pcap_windows.go │ │ ├── test_dns.pcap │ │ ├── test_ethernet.pcap │ │ └── test_loopback.pcap │ │ ├── time.go │ │ └── writer.go ├── gopherjs │ └── gopherjs │ │ ├── LICENSE │ │ └── js │ │ └── js.go ├── jtolds │ └── gls │ │ ├── LICENSE │ │ ├── README.md │ │ ├── context.go │ │ ├── gen_sym.go │ │ ├── gid.go │ │ ├── id_pool.go │ │ ├── stack_tags.go │ │ ├── stack_tags_js.go │ │ └── stack_tags_main.go ├── smarty │ └── assertions │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── CONTRIBUTING.md │ │ ├── LICENSE.md │ │ ├── Makefile │ │ ├── README.md │ │ ├── collections.go │ │ ├── doc.go │ │ ├── equal_method.go │ │ ├── equality.go │ │ ├── equality_diff.go │ │ ├── equality_specs.go │ │ ├── filter.go │ │ ├── internal │ │ ├── go-diff │ │ │ ├── AUTHORS │ │ │ ├── CONTRIBUTORS │ │ │ ├── LICENSE │ │ │ └── diffmatchpatch │ │ │ │ ├── diff.go │ │ │ │ ├── diffmatchpatch.go │ │ │ │ ├── match.go │ │ │ │ ├── mathutil.go │ │ │ │ ├── operation_string.go │ │ │ │ ├── patch.go │ │ │ │ └── stringutil.go │ │ ├── go-render │ │ │ ├── LICENSE │ │ │ └── render │ │ │ │ ├── render.go │ │ │ │ └── render_time.go │ │ └── oglematchers │ │ │ ├── .gitignore │ │ │ ├── .travis.yml │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── any_of.go │ │ │ ├── contains.go │ │ │ ├── deep_equals.go │ │ │ ├── equals.go │ │ │ ├── greater_or_equal.go │ │ │ ├── greater_than.go │ │ │ ├── less_or_equal.go │ │ │ ├── less_than.go │ │ │ ├── matcher.go │ │ │ ├── not.go │ │ │ └── transform_description.go │ │ ├── messages.go │ │ ├── panic.go │ │ ├── quantity.go │ │ ├── serializer.go │ │ ├── strings.go │ │ ├── time.go │ │ └── type.go └── smartystreets │ └── goconvey │ ├── LICENSE.md │ └── convey │ ├── assertions.go │ ├── context.go │ ├── convey.goconvey │ ├── discovery.go │ ├── doc.go │ ├── gotest │ └── utils.go │ ├── init.go │ ├── nilReporter.go │ ├── reporting │ ├── console.go │ ├── doc.go │ ├── dot.go │ ├── gotest.go │ ├── init.go │ ├── json.go │ ├── printer.go │ ├── problems.go │ ├── reporter.go │ ├── reporting.goconvey │ ├── reports.go │ ├── statistics.go │ └── story.go │ └── update_assertions.sh ├── golang.org └── x │ └── sys │ ├── LICENSE │ ├── PATENTS │ └── windows │ ├── aliases.go │ ├── dll_windows.go │ ├── empty.s │ ├── env_windows.go │ ├── eventlog.go │ ├── exec_windows.go │ ├── memory_windows.go │ ├── mkerrors.bash │ ├── mkknownfolderids.bash │ ├── mksyscall.go │ ├── race.go │ ├── race0.go │ ├── security_windows.go │ ├── service.go │ ├── setupapi_windows.go │ ├── str.go │ ├── syscall.go │ ├── syscall_windows.go │ ├── types_windows.go │ ├── types_windows_386.go │ ├── types_windows_amd64.go │ ├── types_windows_arm.go │ ├── types_windows_arm64.go │ ├── zerrors_windows.go │ ├── zknownfolderids_windows.go │ └── zsyscall_windows.go └── modules.txt /.dockerignore: -------------------------------------------------------------------------------- 1 | .github 2 | examples 3 | *.tar.gz 4 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "gomod" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "weekly" 12 | -------------------------------------------------------------------------------- /.github/workflows/codacy.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | 6 | # This workflow checks out code, performs a Codacy security scan 7 | # and integrates the results with the 8 | # GitHub Advanced Security code scanning feature. For more information on 9 | # the Codacy security scan action usage and parameters, see 10 | # https://github.com/codacy/codacy-analysis-cli-action. 11 | # For more information on Codacy Analysis CLI in general, see 12 | # https://github.com/codacy/codacy-analysis-cli. 13 | 14 | name: Codacy Security Scan 15 | 16 | on: 17 | push: 18 | branches: [ "master" ] 19 | pull_request: 20 | # The branches below must be a subset of the branches above 21 | branches: [ "master" ] 22 | schedule: 23 | - cron: '29 15 * * 5' 24 | 25 | permissions: 26 | contents: read 27 | 28 | jobs: 29 | codacy-security-scan: 30 | permissions: 31 | contents: read # for actions/checkout to fetch code 32 | security-events: write # for github/codeql-action/upload-sarif to upload SARIF results 33 | actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status 34 | name: Codacy Security Scan 35 | runs-on: ubuntu-latest 36 | steps: 37 | # Checkout the repository to the GitHub Actions runner 38 | - name: Checkout code 39 | uses: actions/checkout@v3 40 | 41 | # Execute Codacy Analysis CLI and generate a SARIF output with the security issues identified during the analysis 42 | - name: Run Codacy Analysis CLI 43 | uses: codacy/codacy-analysis-cli-action@d840f886c4bd4edc059706d09c6a1586111c540b 44 | with: 45 | # Check https://github.com/codacy/codacy-analysis-cli#project-token to get your project token from your Codacy repository 46 | # You can also omit the token and run the tools that support default configurations 47 | project-token: ${{ secrets.CODACY_PROJECT_TOKEN }} 48 | verbose: true 49 | output: results.sarif 50 | format: sarif 51 | # Adjust severity of non-security issues 52 | gh-code-scanning-compat: true 53 | # Force 0 exit code to allow SARIF file generation 54 | # This will handover control about PR rejection to the GitHub side 55 | max-allowed-issues: 2147483647 56 | 57 | # Upload the SARIF file generated in the previous step 58 | - name: Upload SARIF results file 59 | uses: github/codeql-action/upload-sarif@v2 60 | with: 61 | sarif_file: results.sarif 62 | -------------------------------------------------------------------------------- /.github/workflows/docker.yml: -------------------------------------------------------------------------------- 1 | name: docker 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | paths-ignore: 8 | - "**.md" 9 | pull_request: 10 | paths-ignore: 11 | - "**.md" 12 | 13 | jobs: 14 | docker: 15 | runs-on: ubuntu-latest 16 | strategy: 17 | matrix: 18 | include: 19 | - ubuntu_version: 24.04 20 | hyperscan_version: 5.4.2 21 | pcre_version: 8.45 22 | go_version: 1.23.3 23 | build_flags: -tags hyperscan_v54 24 | # - ubuntu_version: 22.04 25 | # hyperscan_version: 5.2.1 26 | # pcre_version: 8.45 27 | # go_version: 1.22.9 28 | # build_flags: -tags hyperscan_v52 29 | # - ubuntu_version: 20.04 30 | # hyperscan_version: 5.1.1 31 | # pcre_version: 8.41 32 | # build_flags: 33 | # go_version: 1.21.13 34 | name: tests @ ubuntu ${{ matrix.ubuntu_version }} for hyperscan ${{ matrix.hyperscan_version }} w/ ${{ matrix.build_flags }} 35 | env: 36 | LATEST_TAG: flier/gohs:${{ matrix.hyperscan_version }} 37 | steps: 38 | - name: Checkout 39 | uses: actions/checkout@v4 40 | 41 | - name: Set up QEMU 42 | uses: docker/setup-qemu-action@v3 43 | 44 | - name: Set up Docker Buildx 45 | uses: docker/setup-buildx-action@v3 46 | 47 | - name: Build and push 48 | uses: docker/build-push-action@v6 49 | with: 50 | load: true 51 | build-args: | 52 | UBUNTU_VERSION=${{ matrix.ubuntu_version }} 53 | HYPERSCAN_VERSION=${{ matrix.hyperscan_version }} 54 | PCRE_VERSION=${{ matrix.pcre_version }} 55 | GO_VERSION=${{ matrix.go_version }} 56 | tags: ${{ env.LATEST_TAG }} 57 | 58 | - name: Test 59 | run: | 60 | docker run --rm ${{ env.LATEST_TAG }} test ${{ matrix.build_flags }} -v ./... 61 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | .idea 10 | .vscode 11 | build 12 | 13 | # Architecture specific extensions/prefixes 14 | *.[568vq] 15 | [568vq].out 16 | 17 | *.cgo1.go 18 | *.cgo2.c 19 | _cgo_defun.c 20 | _cgo_gotypes.go 21 | _cgo_export.* 22 | 23 | _testmain.go 24 | 25 | *.exe 26 | *.test 27 | *.prof 28 | 29 | *.out 30 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2021 Flier Lu 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /bench/cpp/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | 3 | project (scan_test) 4 | 5 | set (CMAKE_CXX_STANDARD 11) 6 | set (CMAKE_CXX_STANDARD_REQUIRED True) 7 | 8 | option (USE_RE2 "benchmark re2" ON) 9 | option (USE_PCRE "benchmark pcre" ON) 10 | 11 | find_package (benchmark REQUIRED) 12 | find_package (PkgConfig REQUIRED) 13 | 14 | pkg_check_modules (HYPERSCAN REQUIRED IMPORTED_TARGET libhs) 15 | 16 | add_executable (scan_test scan_test.cpp) 17 | 18 | if (USE_RE2) 19 | pkg_check_modules (RE2 REQUIRED IMPORTED_TARGET re2) 20 | 21 | if (RE2_FOUND) 22 | target_include_directories (scan_test PRIVATE ${RE2_INCLUDE_DIRS}) 23 | target_link_libraries (scan_test PkgConfig::RE2) 24 | set (HAVE_RE2 1) 25 | else () 26 | message (FATAL_ERROR "re2 not found") 27 | endif () 28 | endif () 29 | 30 | if (USE_PCRE) 31 | pkg_check_modules (PCRE2 REQUIRED IMPORTED_TARGET libpcre2-8) 32 | 33 | if (PCRE2_FOUND) 34 | target_include_directories (scan_test PRIVATE ${PCRE2_INCLUDE_DIRS}) 35 | target_link_libraries (scan_test PkgConfig::PCRE2) 36 | set (HAVE_PCRE2 1) 37 | else () 38 | message (FATAL_ERROR "pcre2 not found") 39 | endif () 40 | endif () 41 | 42 | configure_file (scan_test.h.in scan_test.h @ONLY) 43 | include_directories(${CMAKE_CURRENT_BINARY_DIR}) 44 | 45 | target_include_directories (scan_test PRIVATE ${HYPERSCAN_INCLUDE_DIRS}) 46 | target_link_libraries (scan_test benchmark::benchmark PkgConfig::HYPERSCAN) 47 | -------------------------------------------------------------------------------- /bench/cpp/scan_test.h.in: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #cmakedefine01 HAVE_RE2 4 | 5 | #cmakedefine01 HAVE_PCRE2 6 | -------------------------------------------------------------------------------- /bench/go/chimera_test.go: -------------------------------------------------------------------------------- 1 | package scan_test 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | 7 | "github.com/flier/gohs/chimera" 8 | ) 9 | 10 | func BenchmarkChimeraBlockScan(b *testing.B) { 11 | isRaceBuilder := strings.HasSuffix(testenv(), "-race") 12 | 13 | for _, data := range benchData { 14 | p := chimera.NewPattern(data.re, chimera.MultiLine) 15 | db, err := chimera.NewBlockDatabase(p) 16 | if err != nil { 17 | b.Fatalf("compile pattern %s: `%s`, %s", data.name, data.re, err) 18 | } 19 | 20 | s, err := chimera.NewScratch(db) 21 | if err != nil { 22 | b.Fatalf("create scratch, %s", err) 23 | } 24 | 25 | m := chimera.HandlerFunc(func(id uint, from, to uint64, flags uint, 26 | captured []*chimera.Capture, context interface{}, 27 | ) chimera.Callback { 28 | return chimera.Terminate 29 | }) 30 | 31 | for _, size := range benchSizes { 32 | if (isRaceBuilder || testing.Short()) && size.n > 1<<10 { 33 | continue 34 | } 35 | t := makeText(size.n) 36 | b.Run(data.name+"/"+size.name, func(b *testing.B) { 37 | b.SetBytes(int64(len(t))) 38 | for i := 0; i < b.N; i++ { 39 | if err = db.Scan(t, s, m, nil); err != nil { 40 | b.Fatalf("match, %s", err) 41 | } 42 | } 43 | }) 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /chimera/api.go: -------------------------------------------------------------------------------- 1 | package chimera 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/flier/gohs/internal/ch" 7 | ) 8 | 9 | // Match reports whether the byte slice b contains any match of the regular expression pattern. 10 | func Match(pattern string, data []byte) (bool, error) { 11 | p, err := ParsePattern(pattern) 12 | if err != nil { 13 | return false, fmt.Errorf("parse pattern, %w", err) 14 | } 15 | 16 | p.Flags |= SingleMatch 17 | 18 | db, err := NewBlockDatabase(p) 19 | if err != nil { 20 | return false, fmt.Errorf("create block database, %w", err) 21 | } 22 | defer db.Close() 23 | 24 | s, err := NewScratch(db) 25 | if err != nil { 26 | return false, fmt.Errorf("create scratch, %w", err) 27 | } 28 | 29 | defer func() { 30 | _ = s.Free() 31 | }() 32 | 33 | h := &ch.MatchRecorder{} 34 | 35 | if err = db.Scan(data, s, h, nil); err != nil { 36 | return false, err //nolint: wrapcheck 37 | } 38 | 39 | return h.Matched(), h.Err 40 | } 41 | 42 | // MatchString reports whether the string s contains any match of the regular expression pattern. 43 | func MatchString(pattern, s string) (matched bool, err error) { 44 | return Match(pattern, []byte(s)) 45 | } 46 | -------------------------------------------------------------------------------- /chimera/api_test.go: -------------------------------------------------------------------------------- 1 | package chimera_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | 8 | "github.com/flier/gohs/chimera" 9 | ) 10 | 11 | func TestMatch(t *testing.T) { 12 | Convey("Given a compatible API for regexp package", t, func() { 13 | Convey("When match a simple expression", func() { 14 | matched, err := chimera.MatchString("test", "abctestdef") 15 | 16 | So(matched, ShouldBeTrue) 17 | So(err, ShouldBeNil) 18 | }) 19 | 20 | Convey("When match a invalid expression", func() { 21 | matched, err := chimera.MatchString(`(?R`, "abctestdef") 22 | 23 | So(matched, ShouldBeFalse) 24 | So(err, ShouldNotBeNil) 25 | }) 26 | }) 27 | } 28 | -------------------------------------------------------------------------------- /chimera/common_test.go: -------------------------------------------------------------------------------- 1 | package chimera_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | 8 | "github.com/flier/gohs/chimera" 9 | "github.com/flier/gohs/hyperscan" 10 | ) 11 | 12 | func TestChimera(t *testing.T) { 13 | Convey("Given a chimera runtimes", t, func() { 14 | So(chimera.Version(), ShouldNotBeEmpty) 15 | }) 16 | } 17 | 18 | func TestBaseDatabase(t *testing.T) { 19 | Convey("Given a block database", t, func() { 20 | So(hyperscan.ValidPlatform(), ShouldBeNil) 21 | 22 | bdb, err := chimera.NewBlockDatabase(&chimera.Pattern{Expression: "test"}) 23 | 24 | So(err, ShouldBeNil) 25 | So(bdb, ShouldNotBeNil) 26 | 27 | Convey("When get size", func() { 28 | size, err := bdb.Size() 29 | 30 | So(err, ShouldBeNil) 31 | So(size, ShouldBeGreaterThan, 800) 32 | }) 33 | 34 | Convey("When get info", func() { 35 | info, err := bdb.Info() 36 | 37 | So(err, ShouldBeNil) 38 | So(info, ShouldNotBeNil) 39 | 40 | _, _, _, err = info.Parse() 41 | So(err, ShouldBeNil) 42 | 43 | Convey("Then get version", func() { 44 | ver, err := info.Version() 45 | 46 | So(err, ShouldBeNil) 47 | So(chimera.Version(), ShouldStartWith, ver) 48 | }) 49 | 50 | Convey("Then get mode", func() { 51 | mode, err := info.Mode() 52 | 53 | So(err, ShouldBeNil) 54 | So(mode, ShouldEqual, hyperscan.BlockMode) 55 | }) 56 | }) 57 | 58 | So(bdb.Close(), ShouldBeNil) 59 | }) 60 | } 61 | 62 | func TestBlockDatabase(t *testing.T) { 63 | Convey("Give a block database", t, func() { 64 | bdb, err := chimera.NewBlockDatabase(&chimera.Pattern{Expression: "test"}) 65 | 66 | So(err, ShouldBeNil) 67 | So(bdb, ShouldNotBeNil) 68 | 69 | Convey("When get info", func() { 70 | info, err := bdb.Info() 71 | 72 | So(err, ShouldBeNil) 73 | So(info, ShouldNotBeNil) 74 | 75 | _, _, _, err = info.Parse() 76 | So(err, ShouldBeNil) 77 | 78 | Convey("Then get mode", func() { 79 | mode, err := info.Mode() 80 | 81 | So(err, ShouldBeNil) 82 | So(mode, ShouldEqual, hyperscan.BlockMode) 83 | }) 84 | }) 85 | 86 | So(bdb.Close(), ShouldBeNil) 87 | }) 88 | } 89 | -------------------------------------------------------------------------------- /chimera/common_v54.go: -------------------------------------------------------------------------------- 1 | //go:build hyperscan_v54 2 | // +build hyperscan_v54 3 | 4 | package chimera 5 | 6 | import "github.com/flier/gohs/internal/ch" 7 | 8 | // ErrUnknown is the unexpected internal error from Hyperscan. 9 | const ErrUnknownHSError Error = ch.ErrUnknownHSError 10 | -------------------------------------------------------------------------------- /chimera/compile_test.go: -------------------------------------------------------------------------------- 1 | package chimera_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | 8 | "github.com/flier/gohs/chimera" 9 | "github.com/flier/gohs/hyperscan" 10 | ) 11 | 12 | func TestCompileFlag(t *testing.T) { 13 | Convey("Given a compile flags", t, func() { 14 | flags := chimera.Caseless | chimera.DotAll | chimera.MultiLine | chimera.SingleMatch | 15 | chimera.Utf8Mode | chimera.UnicodeProperty 16 | 17 | So(flags.String(), ShouldEqual, "8HWims") 18 | 19 | Convey("When parse valid flags", func() { 20 | f, err := chimera.ParseCompileFlag("ismH8W") 21 | 22 | So(f, ShouldEqual, flags) 23 | So(err, ShouldBeNil) 24 | }) 25 | 26 | Convey("When parse invalid flags", func() { 27 | f, err := chimera.ParseCompileFlag("abc") 28 | 29 | So(f, ShouldEqual, 0) 30 | So(err, ShouldNotBeNil) 31 | }) 32 | }) 33 | } 34 | 35 | func TestDatabaseBuilder(t *testing.T) { 36 | Convey("Given a DatabaseBuilder", t, func() { 37 | b := chimera.DatabaseBuilder{} 38 | 39 | Convey("When build without patterns", func() { 40 | db, err := b.Build() 41 | 42 | So(db, ShouldBeNil) 43 | So(err, ShouldNotBeNil) 44 | }) 45 | 46 | Convey("When build with a simple expression", func() { 47 | db, err := b.AddExpressions("test").Build() 48 | 49 | So(err, ShouldBeNil) 50 | So(db, ShouldNotBeNil) 51 | 52 | So(db.Close(), ShouldBeNil) 53 | }) 54 | 55 | Convey("When build with some complicated expression", func() { 56 | db, err := b.AddExpressions("test", hyperscan.EmailAddress, hyperscan.IPv4Address, hyperscan.CreditCard).Build() 57 | 58 | So(err, ShouldBeNil) 59 | So(db, ShouldNotBeNil) 60 | 61 | info, err := db.Info() 62 | 63 | So(err, ShouldBeNil) 64 | 65 | mode, err := info.Mode() 66 | 67 | So(err, ShouldBeNil) 68 | So(mode, ShouldEqual, hyperscan.BlockMode) 69 | 70 | So(db.Close(), ShouldBeNil) 71 | }) 72 | }) 73 | } 74 | 75 | func TestCompile(t *testing.T) { 76 | Convey("Given compile some expressions", t, func() { 77 | Convey("When compile a simple expression", func() { 78 | db, err := chimera.Compile("test") 79 | 80 | So(db, ShouldNotBeNil) 81 | So(err, ShouldBeNil) 82 | 83 | So(db.Close(), ShouldBeNil) 84 | }) 85 | 86 | Convey("When compile a complex expression", func() { 87 | db, err := chimera.Compile(hyperscan.CreditCard) 88 | 89 | So(db, ShouldNotBeNil) 90 | So(err, ShouldBeNil) 91 | 92 | So(db.Close(), ShouldBeNil) 93 | }) 94 | }) 95 | } 96 | -------------------------------------------------------------------------------- /chimera/example_api_test.go: -------------------------------------------------------------------------------- 1 | package chimera_test 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/flier/gohs/chimera" 7 | ) 8 | 9 | func ExampleMatch() { 10 | matched, err := chimera.Match(`foo.*`, []byte(`seafood`)) 11 | fmt.Println(matched, err) 12 | matched, err = chimera.Match(`bar.*`, []byte(`seafood`)) 13 | fmt.Println(matched, err) 14 | matched, err = chimera.Match(`a(b`, []byte(`seafood`)) 15 | fmt.Println(matched, err) 16 | // Output: 17 | // true 18 | // false 19 | // false create block database, PCRE compilation failed: missing ). 20 | } 21 | -------------------------------------------------------------------------------- /chimera/example_compile_test.go: -------------------------------------------------------------------------------- 1 | package chimera_test 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/flier/gohs/chimera" 8 | ) 9 | 10 | // This example demonstrates construct and match a pattern. 11 | func ExamplePattern() { 12 | p := chimera.NewPattern(`foo.*bar`, chimera.Caseless) 13 | fmt.Println(p) 14 | 15 | db, err := chimera.NewBlockDatabase(p) 16 | fmt.Println(err) 17 | 18 | found := db.MatchString("fooxyzbarbar") 19 | fmt.Println(found) 20 | 21 | // Output: 22 | // /foo.*bar/i 23 | // 24 | // true 25 | } 26 | 27 | // This example demonstrates parsing pattern with id and flags. 28 | func ExampleParsePattern() { 29 | p, err := chimera.ParsePattern("3:/foobar/i8") 30 | 31 | fmt.Println(err) 32 | fmt.Println(p.ID) 33 | fmt.Println(p.Expression) 34 | fmt.Println(p.Flags) 35 | 36 | // Output: 37 | // 38 | // 3 39 | // foobar 40 | // 8i 41 | } 42 | 43 | // This example demonstrates parsing patterns with comment. 44 | func ExampleParsePatterns() { 45 | patterns, err := chimera.ParsePatterns(strings.NewReader(` 46 | # empty line and comment will be skipped 47 | 48 | 1:/hatstand.*teakettle/s 49 | 2:/(hatstand|teakettle)/iH 50 | 3:/^.{10,20}hatstand/m 51 | `)) 52 | 53 | fmt.Println(err) 54 | 55 | for _, p := range patterns { 56 | fmt.Println(p) 57 | } 58 | 59 | // Output: 60 | // 61 | // 1:/hatstand.*teakettle/s 62 | // 2:/(hatstand|teakettle)/Hi 63 | // 3:/^.{10,20}hatstand/m 64 | } 65 | -------------------------------------------------------------------------------- /chimera/example_runtime_test.go: -------------------------------------------------------------------------------- 1 | package chimera_test 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/flier/gohs/chimera" 7 | ) 8 | 9 | func ExampleBlockScanner() { 10 | p, err := chimera.ParsePattern(`foo(bar)+`) 11 | if err != nil { 12 | fmt.Println("parse pattern failed,", err) 13 | return 14 | } 15 | 16 | // Create new block database with pattern 17 | db, err := chimera.NewBlockDatabase(p) 18 | if err != nil { 19 | fmt.Println("create database failed,", err) 20 | return 21 | } 22 | defer db.Close() 23 | 24 | // Create new scratch for scanning 25 | s, err := chimera.NewScratch(db) 26 | if err != nil { 27 | fmt.Println("create scratch failed,", err) 28 | return 29 | } 30 | 31 | defer func() { 32 | _ = s.Free() 33 | }() 34 | 35 | // Record matching text 36 | type Match struct { 37 | from uint64 38 | to uint64 39 | } 40 | 41 | var matches []Match 42 | 43 | handler := chimera.HandlerFunc(func(id uint, from, to uint64, flags uint, 44 | captured []*chimera.Capture, ctx interface{}, 45 | ) chimera.Callback { 46 | matches = append(matches, Match{from, to}) 47 | return chimera.Continue 48 | }) 49 | 50 | data := []byte("hello foobarbar!") 51 | 52 | // Scan data block with handler 53 | if err := db.Scan(data, s, handler, nil); err != nil { 54 | fmt.Println("database scan failed,", err) 55 | return 56 | } 57 | 58 | // chimera will reports all matches 59 | for _, m := range matches { 60 | fmt.Println("match [", m.from, ":", m.to, "]", string(data[m.from:m.to])) 61 | } 62 | 63 | // Output: 64 | // match [ 6 : 15 ] foobarbar 65 | } 66 | -------------------------------------------------------------------------------- /chimera/pattern.go: -------------------------------------------------------------------------------- 1 | package chimera 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "io" 7 | "strconv" 8 | "strings" 9 | 10 | "github.com/flier/gohs/internal/ch" 11 | ) 12 | 13 | // Pattern is a matching pattern. 14 | type Pattern ch.Pattern 15 | 16 | // NewPattern returns a new pattern base on expression and compile flags. 17 | func NewPattern(expr string, flags CompileFlag) *Pattern { 18 | return &Pattern{Expression: expr, Flags: flags} 19 | } 20 | 21 | /* 22 | ParsePattern parse pattern from a formated string. 23 | 24 | :// 25 | 26 | For example, the following pattern will match `test` in the caseless and multi-lines mode 27 | 28 | /test/im 29 | */ 30 | func ParsePattern(s string) (*Pattern, error) { 31 | var p Pattern 32 | 33 | i := strings.Index(s, ":/") 34 | j := strings.LastIndex(s, "/") 35 | 36 | if i > 0 && j > i+1 { 37 | id, err := strconv.Atoi(s[:i]) 38 | if err != nil { 39 | return nil, fmt.Errorf("pattern id `%s`, %w", s[:i], ErrInvalid) 40 | } 41 | 42 | p.ID = id 43 | s = s[i+1:] 44 | } 45 | 46 | if n := strings.LastIndex(s, "/"); n > 1 && strings.HasPrefix(s, "/") { 47 | p.Expression = s[1:n] 48 | s = s[n+1:] 49 | 50 | flags, err := ParseCompileFlag(s) 51 | if err != nil { 52 | return nil, fmt.Errorf("pattern flags `%s`, %w", s, err) 53 | } 54 | 55 | p.Flags = flags 56 | } else { 57 | p.Expression = s 58 | } 59 | 60 | return &p, nil 61 | } 62 | 63 | func (p *Pattern) String() string { 64 | var b strings.Builder 65 | 66 | if p.ID > 0 { 67 | fmt.Fprintf(&b, "%d:", p.ID) 68 | } 69 | 70 | fmt.Fprintf(&b, "/%s/%s", p.Expression, p.Flags) 71 | 72 | return b.String() 73 | } 74 | 75 | // Patterns is a set of matching patterns. 76 | type Patterns []*Pattern 77 | 78 | // ParsePatterns parse lines as `Patterns`. 79 | func ParsePatterns(r io.Reader) (patterns Patterns, err error) { 80 | s := bufio.NewScanner(r) 81 | 82 | for s.Scan() { 83 | line := strings.TrimSpace(s.Text()) 84 | 85 | if line == "" { 86 | // skip empty line 87 | continue 88 | } 89 | 90 | if strings.HasPrefix(line, "#") { 91 | // skip comment 92 | continue 93 | } 94 | 95 | p, err := ParsePattern(line) 96 | if err != nil { 97 | return nil, err 98 | } 99 | 100 | patterns = append(patterns, p) 101 | } 102 | 103 | return 104 | } 105 | 106 | func (p Patterns) Patterns() (r []*ch.Pattern) { 107 | r = make([]*ch.Pattern, len(p)) 108 | for i, pat := range p { 109 | r[i] = (*ch.Pattern)(pat) 110 | } 111 | return 112 | } 113 | -------------------------------------------------------------------------------- /chimera/pattern_test.go: -------------------------------------------------------------------------------- 1 | package chimera_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | 8 | "github.com/flier/gohs/chimera" 9 | ) 10 | 11 | //nolint:funlen 12 | func TestPattern(t *testing.T) { 13 | Convey("Give a pattern", t, func() { 14 | Convey("When parse with flags", func() { 15 | p, err := chimera.ParsePattern(`/test/im`) 16 | 17 | So(err, ShouldBeNil) 18 | So(p, ShouldNotBeNil) 19 | So(p.Expression, ShouldEqual, "test") 20 | So(p.Flags, ShouldEqual, chimera.Caseless|chimera.MultiLine) 21 | 22 | So(p.Expression, ShouldEqual, "test") 23 | So(p.String(), ShouldEqual, `/test/im`) 24 | 25 | Convey("When pattern contains forward slash", func() { 26 | p, err := chimera.ParsePattern(`/te/st/im`) 27 | 28 | So(err, ShouldBeNil) 29 | So(p, ShouldNotBeNil) 30 | So(p.Expression, ShouldEqual, "te/st") 31 | So(p.Flags, ShouldEqual, chimera.Caseless|chimera.MultiLine) 32 | 33 | So(p.String(), ShouldEqual, "/te/st/im") 34 | }) 35 | }) 36 | 37 | Convey("When parse pattern with id and flags", func() { 38 | p, err := chimera.ParsePattern("3:/foobar/i8") 39 | 40 | So(err, ShouldBeNil) 41 | So(p.ID, ShouldEqual, 3) 42 | So(p.Expression, ShouldEqual, "foobar") 43 | So(p.Flags, ShouldEqual, chimera.Caseless|chimera.Utf8Mode) 44 | }) 45 | 46 | Convey("When parse with a lot of flags", func() { 47 | p, err := chimera.ParsePattern(`/test/ismH8W`) 48 | 49 | So(err, ShouldBeNil) 50 | So(p, ShouldNotBeNil) 51 | So(p.Expression, ShouldEqual, "test") 52 | So(p.Flags, ShouldEqual, chimera.Caseless|chimera.DotAll|chimera.MultiLine|chimera.SingleMatch| 53 | chimera.Utf8Mode|chimera.UnicodeProperty) 54 | 55 | So(p.Flags.String(), ShouldEqual, "8HWims") 56 | So(p.String(), ShouldEqual, "/test/8HWims") 57 | }) 58 | 59 | Convey("When parse without flags", func() { 60 | p, err := chimera.ParsePattern(`test`) 61 | 62 | So(err, ShouldBeNil) 63 | So(p, ShouldNotBeNil) 64 | So(p.Expression, ShouldEqual, "test") 65 | So(p.Flags, ShouldEqual, 0) 66 | 67 | Convey("When pattern contains forward slash", func() { 68 | p, err := chimera.ParsePattern(`te/st`) 69 | 70 | So(err, ShouldBeNil) 71 | So(p, ShouldNotBeNil) 72 | So(p.Expression, ShouldEqual, "te/st") 73 | So(p.Flags, ShouldEqual, 0) 74 | }) 75 | }) 76 | 77 | Convey("When quote a string", func() { 78 | So(chimera.Quote("test"), ShouldEqual, "`test`") 79 | So(chimera.Quote("`can't backquote this`"), ShouldEqual, "\"`can't backquote this`\"") 80 | }) 81 | }) 82 | } 83 | -------------------------------------------------------------------------------- /chimera/runtime.go: -------------------------------------------------------------------------------- 1 | package chimera 2 | 3 | import ( 4 | "github.com/flier/gohs/internal/ch" 5 | ) 6 | 7 | // Callback return value used to tell the Chimera matcher what to do after processing this match. 8 | type Callback = ch.Callback 9 | 10 | const ( 11 | Continue Callback = ch.Continue // Continue matching. 12 | Terminate Callback = ch.Terminate // Terminate matching. 13 | SkipPattern Callback = ch.SkipPattern // Skip remaining matches for this ID and continue. 14 | ) 15 | 16 | // Capture representing a captured subexpression within a match. 17 | type Capture = ch.Capture 18 | 19 | // Type used to differentiate the errors raised with the `ErrorEventHandler` callback. 20 | type ErrorEvent = ch.ErrorEvent //nolint: errname 21 | 22 | const ( 23 | // PCRE hits its match limit and reports PCRE_ERROR_MATCHLIMIT. 24 | ErrMatchLimit ErrorEvent = ch.ErrMatchLimit 25 | // PCRE hits its recursion limit and reports PCRE_ERROR_RECURSIONLIMIT. 26 | ErrRecursionLimit ErrorEvent = ch.ErrRecursionLimit 27 | ) 28 | 29 | // Definition of the chimera event callback handler. 30 | type Handler interface { 31 | // OnMatch will be invoked whenever a match is located in the target data during the execution of a scan. 32 | OnMatch(id uint, from, to uint64, flags uint, captured []*Capture, context interface{}) Callback 33 | 34 | // OnError will be invoked when an error event occurs during matching; 35 | // this indicates that some matches for a given expression may not be reported. 36 | OnError(event ErrorEvent, id uint, info, context interface{}) Callback 37 | } 38 | 39 | // HandlerFunc type is an adapter to allow the use of ordinary functions as Chimera handlers. 40 | // If f is a function with the appropriate signature, HandlerFunc(f) is a Handler that calls f. 41 | type HandlerFunc func(id uint, from, to uint64, flags uint, captured []*Capture, context interface{}) Callback 42 | 43 | // OnMatch will be invoked whenever a match is located in the target data during the execution of a scan. 44 | func (f HandlerFunc) OnMatch(id uint, from, to uint64, flags uint, captured []*Capture, ctx interface{}) Callback { 45 | return f(id, from, to, flags, captured, ctx) 46 | } 47 | 48 | // OnError will be invoked when an error event occurs during matching; 49 | // this indicates that some matches for a given expression may not be reported. 50 | func (f HandlerFunc) OnError(event ErrorEvent, id uint, info, context interface{}) Callback { 51 | return Terminate 52 | } 53 | -------------------------------------------------------------------------------- /chimera/runtime_test.go: -------------------------------------------------------------------------------- 1 | package chimera_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | 8 | "github.com/flier/gohs/chimera" 9 | ) 10 | 11 | type ( 12 | BlockDatabaseConstructor func(patterns ...*chimera.Pattern) (chimera.BlockDatabase, error) 13 | ) 14 | 15 | var blockDatabaseConstructors = map[string]BlockDatabaseConstructor{ 16 | "normal": chimera.NewBlockDatabase, 17 | "managed": chimera.NewManagedBlockDatabase, 18 | } 19 | 20 | func TestBlockScanner(t *testing.T) { 21 | for dbType, dbConstructor := range blockDatabaseConstructors { 22 | Convey("Given a "+dbType+" block database", t, func() { 23 | bdb, err := dbConstructor(chimera.NewPattern(`\d+`, 0)) //nolint: scopelint 24 | 25 | So(err, ShouldBeNil) 26 | So(bdb, ShouldNotBeNil) 27 | 28 | Convey("When scan a string", func() { 29 | var matches [][]uint64 30 | 31 | matched := func(id uint, from, to uint64, flags uint, 32 | captured []*chimera.Capture, context interface{}, 33 | ) chimera.Callback { 34 | matches = append(matches, []uint64{from, to}) 35 | 36 | return chimera.Continue 37 | } 38 | 39 | err = bdb.Scan([]byte("abc123def456"), nil, chimera.HandlerFunc(matched), nil) 40 | 41 | So(err, ShouldBeNil) 42 | So(matches, ShouldResemble, [][]uint64{{3, 6}, {9, 12}}) 43 | }) 44 | }) 45 | } 46 | } 47 | 48 | func TestBlockMatcher(t *testing.T) { 49 | for dbType, dbConstructor := range blockDatabaseConstructors { 50 | Convey("Given a "+dbType+" block database", t, func() { 51 | bdb, err := dbConstructor(chimera.NewPattern(`\d+`, 0)) //nolint: scopelint 52 | 53 | So(err, ShouldBeNil) 54 | So(bdb, ShouldNotBeNil) 55 | 56 | Convey("When match the string", func() { 57 | So(bdb.MatchString("123"), ShouldBeTrue) 58 | So(bdb.MatchString("abc123def456"), ShouldBeTrue) 59 | }) 60 | 61 | Convey("When find the leftmost matched string index", func() { 62 | So(bdb.FindStringIndex("123"), ShouldResemble, []int{0, 3}) 63 | So(bdb.FindStringIndex("abc123def456"), ShouldResemble, []int{3, 6}) 64 | }) 65 | 66 | Convey("When find the leftmost matched string", func() { 67 | So(bdb.FindString("123"), ShouldEqual, "123") 68 | So(bdb.FindString("abc123def456"), ShouldEqual, "123") 69 | }) 70 | 71 | Convey("When find all the matched string index", func() { 72 | So(bdb.FindAllStringIndex("123", -1), ShouldResemble, [][]int{{0, 3}}) 73 | So(bdb.FindAllStringIndex("abc123def456", -1), ShouldResemble, [][]int{{3, 6}, {9, 12}}) 74 | }) 75 | 76 | Convey("When find all the matched string", func() { 77 | So(bdb.FindAllString("abc123def456", -1), ShouldResemble, 78 | []string{"123", "456"}) 79 | }) 80 | 81 | Convey("When find all the first 4 matched string index", func() { 82 | So(bdb.FindAllStringIndex("abc123def456", 1), ShouldResemble, 83 | [][]int{{3, 6}}) 84 | }) 85 | 86 | Convey("When find all the first 4 matched string", func() { 87 | So(bdb.FindAllString("abc123def456", 1), ShouldResemble, 88 | []string{"123"}) 89 | }) 90 | }) 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /chimera/scratch.go: -------------------------------------------------------------------------------- 1 | package chimera 2 | 3 | import ( 4 | "runtime" 5 | 6 | "github.com/flier/gohs/internal/ch" 7 | ) 8 | 9 | // Scratch is a Chimera scratch space. 10 | type Scratch struct { 11 | s ch.Scratch 12 | } 13 | 14 | // NewScratch allocate a "scratch" space for use by Chimera. 15 | // This is required for runtime use, and one scratch space per thread, 16 | // or concurrent caller, is required. 17 | func NewScratch(db Database) (*Scratch, error) { 18 | s, err := ch.AllocScratch(db.(database).c()) 19 | if err != nil { 20 | return nil, err //nolint: wrapcheck 21 | } 22 | 23 | return &Scratch{s}, nil 24 | } 25 | 26 | // NewManagedScratch is a wrapper for NewScratch that sets 27 | // a finalizer on the Scratch instance so that memory is freed 28 | // once the object is no longer in use. 29 | func NewManagedScratch(db Database) (*Scratch, error) { 30 | s, err := NewScratch(db) 31 | if err != nil { 32 | return nil, err 33 | } 34 | 35 | runtime.SetFinalizer(s, func(scratch *Scratch) { 36 | _ = scratch.Free() 37 | }) 38 | return s, nil 39 | } 40 | 41 | // Size provides the size of the given scratch space. 42 | func (s *Scratch) Size() (int, error) { return ch.ScratchSize(s.s) } //nolint: wrapcheck 43 | 44 | // Realloc reallocate the scratch for another database. 45 | func (s *Scratch) Realloc(db Database) error { 46 | r, _ := db.(database) 47 | 48 | return ch.ReallocScratch(r.c(), &s.s) //nolint: wrapcheck 49 | } 50 | 51 | // Clone allocate a scratch space that is a clone of an existing scratch space. 52 | func (s *Scratch) Clone() (*Scratch, error) { 53 | cloned, err := ch.CloneScratch(s.s) 54 | if err != nil { 55 | return nil, err //nolint: wrapcheck 56 | } 57 | 58 | return &Scratch{cloned}, nil 59 | } 60 | 61 | // Free a scratch block previously allocated. 62 | func (s *Scratch) Free() error { return ch.FreeScratch(s.s) } //nolint: wrapcheck 63 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.9" 2 | services: 3 | hyperscan-5.4: 4 | build: 5 | context: . 6 | labels: 7 | hyperscan: 5.4 8 | args: 9 | HYPERSCAN_VERSION: 5.4.1 10 | command: test -tags hyperscan_v54 ./... 11 | hyperscan-5.2: 12 | build: 13 | context: . 14 | labels: 15 | hyperscan: 5.2 16 | args: 17 | HYPERSCAN_VERSION: 5.2.1 18 | hyperscan-4.7: 19 | build: 20 | context: . 21 | labels: 22 | hyperscan: 4.7 23 | args: 24 | UBUNTU_VERSION: 18.04 25 | HYPERSCAN_VERSION: 4.7.0 26 | PCRE_VERSION: 8.41 27 | GO_BUILD_TAGS: -tags hyperscan_v4 28 | command: test -tags hyperscan_v4 ./hyperscan/... ./internal/hs/... 29 | -------------------------------------------------------------------------------- /examples/pcapscan/patterns: -------------------------------------------------------------------------------- 1 | 10002:/google/i 2 | 10001:/foobar/is 3 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/flier/gohs 2 | 3 | go 1.18 4 | 5 | require ( 6 | github.com/google/gopacket v1.1.19 7 | github.com/smartystreets/goconvey v1.8.1 8 | ) 9 | 10 | require ( 11 | github.com/gopherjs/gopherjs v1.17.2 // indirect 12 | github.com/jtolds/gls v4.20.0+incompatible // indirect 13 | github.com/smarty/assertions v1.15.0 // indirect 14 | golang.org/x/net v0.23.0 // indirect 15 | golang.org/x/sys v0.18.0 // indirect 16 | ) 17 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= 2 | github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= 3 | github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= 4 | github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= 5 | github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= 6 | github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= 7 | github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY= 8 | github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= 9 | github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= 10 | github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= 11 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 12 | golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 13 | golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 14 | golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= 15 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 16 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 17 | golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= 18 | golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= 19 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 20 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 21 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 22 | golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= 23 | golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 24 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 25 | golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= 26 | golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 27 | -------------------------------------------------------------------------------- /hyperscan/api.go: -------------------------------------------------------------------------------- 1 | package hyperscan 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | 7 | "github.com/flier/gohs/internal/hs" 8 | ) 9 | 10 | // Match reports whether the byte slice b contains any match of the regular expression pattern. 11 | func Match(pattern string, data []byte) (bool, error) { 12 | p, err := ParsePattern(pattern) 13 | if err != nil { 14 | return false, fmt.Errorf("parse pattern, %w", err) 15 | } 16 | 17 | p.Flags |= SingleMatch 18 | 19 | db, err := NewBlockDatabase(p) 20 | if err != nil { 21 | return false, fmt.Errorf("create block database, %w", err) 22 | } 23 | defer db.Close() 24 | 25 | s, err := NewScratch(db) 26 | if err != nil { 27 | return false, fmt.Errorf("create scratch, %w", err) 28 | } 29 | 30 | defer func() { 31 | _ = s.Free() 32 | }() 33 | 34 | h := &hs.MatchRecorder{} 35 | 36 | if err = db.Scan(data, s, h.Handle, nil); err != nil { 37 | return false, fmt.Errorf("match pattern, %w", err) 38 | } 39 | 40 | return h.Matched(), h.Err 41 | } 42 | 43 | // MatchReader reports whether the text returned by the Reader contains any match of the regular expression pattern. 44 | func MatchReader(pattern string, reader io.Reader) (bool, error) { 45 | p, err := ParsePattern(pattern) 46 | if err != nil { 47 | return false, fmt.Errorf("parse pattern, %w", err) 48 | } 49 | 50 | p.Flags |= SingleMatch 51 | 52 | db, err := NewStreamDatabase(p) 53 | if err != nil { 54 | return false, fmt.Errorf("create stream database, %w", err) 55 | } 56 | defer db.Close() 57 | 58 | s, err := NewScratch(db) 59 | if err != nil { 60 | return false, fmt.Errorf("create scratch, %w", err) 61 | } 62 | 63 | defer func() { 64 | _ = s.Free() 65 | }() 66 | 67 | h := &hs.MatchRecorder{} 68 | 69 | if err = db.Scan(reader, s, h.Handle, nil); err != nil { 70 | return false, fmt.Errorf("match pattern, %w", err) 71 | } 72 | 73 | return h.Matched(), h.Err 74 | } 75 | 76 | // MatchString reports whether the string s contains any match of the regular expression pattern. 77 | func MatchString(pattern, s string) (matched bool, err error) { 78 | return Match(pattern, []byte(s)) 79 | } 80 | -------------------------------------------------------------------------------- /hyperscan/api_test.go: -------------------------------------------------------------------------------- 1 | package hyperscan_test 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | 7 | . "github.com/smartystreets/goconvey/convey" 8 | 9 | "github.com/flier/gohs/hyperscan" 10 | ) 11 | 12 | func TestMatch(t *testing.T) { 13 | Convey("Given a compatible API for regexp package", t, func() { 14 | Convey("When match a simple expression", func() { 15 | matched, err := hyperscan.MatchString("test", "abctestdef") 16 | 17 | So(matched, ShouldBeTrue) 18 | So(err, ShouldBeNil) 19 | }) 20 | 21 | Convey("When match a invalid expression", func() { 22 | matched, err := hyperscan.MatchString(`\R`, "abctestdef") 23 | 24 | So(matched, ShouldBeFalse) 25 | So(err, ShouldNotBeNil) 26 | }) 27 | 28 | Convey("When match a simple expression with io.Reader", func() { 29 | var buf bytes.Buffer 30 | 31 | buf.Write(make([]byte, 1024*1024)) 32 | buf.WriteString("abctestdef") 33 | 34 | matched, err := hyperscan.MatchReader("test", &buf) 35 | 36 | So(matched, ShouldBeTrue) 37 | So(err, ShouldBeNil) 38 | }) 39 | }) 40 | } 41 | -------------------------------------------------------------------------------- /hyperscan/compile_v5.go: -------------------------------------------------------------------------------- 1 | //go:build !hyperscan_v4 2 | // +build !hyperscan_v4 3 | 4 | package hyperscan 5 | 6 | import ( 7 | "github.com/flier/gohs/internal/hs" 8 | ) 9 | 10 | const ( 11 | // Combination represents logical combination. 12 | Combination CompileFlag = hs.Combination 13 | // Quiet represents don't do any match reporting. 14 | Quiet CompileFlag = hs.Quiet 15 | ) 16 | -------------------------------------------------------------------------------- /hyperscan/compile_v5_test.go: -------------------------------------------------------------------------------- 1 | //go:build !hyperscan_v4 2 | // +build !hyperscan_v4 3 | 4 | package hyperscan_test 5 | 6 | import ( 7 | "testing" 8 | 9 | . "github.com/smartystreets/goconvey/convey" 10 | 11 | "github.com/flier/gohs/hyperscan" 12 | ) 13 | 14 | func TestDatabaseBuilderV5(t *testing.T) { 15 | Convey("Given a DatabaseBuilder (v5)", t, func() { 16 | b := hyperscan.DatabaseBuilder{} 17 | Convey("When build with some combination expression", func() { 18 | db, err := b.AddExpressions("101:/abc/Q", "102:/def/Q", "/(101&102)/Co").Build() 19 | 20 | So(err, ShouldBeNil) 21 | So(db, ShouldNotBeNil) 22 | 23 | info, err := db.Info() 24 | 25 | So(err, ShouldBeNil) 26 | 27 | mode, err := info.Mode() 28 | 29 | So(err, ShouldBeNil) 30 | So(mode, ShouldEqual, hyperscan.BlockMode) 31 | 32 | So(db.Close(), ShouldBeNil) 33 | }) 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /hyperscan/example_api_test.go: -------------------------------------------------------------------------------- 1 | package hyperscan_test 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/flier/gohs/hyperscan" 8 | ) 9 | 10 | func ExampleMatch() { 11 | matched, err := hyperscan.Match(`foo.*`, []byte(`seafood`)) 12 | fmt.Println(matched, err) 13 | matched, err = hyperscan.Match(`bar.*`, []byte(`seafood`)) 14 | fmt.Println(matched, err) 15 | matched, err = hyperscan.Match(`a(b`, []byte(`seafood`)) 16 | fmt.Println(matched, err) 17 | // Output: 18 | // true 19 | // false 20 | // false parse pattern, pattern `a(b`, Missing close parenthesis for group started at index 1. 21 | } 22 | 23 | func ExampleMatchReader() { 24 | s := strings.NewReader(strings.Repeat("a", 4096) + `seafood`) 25 | matched, err := hyperscan.MatchReader(`foo.*`, s) 26 | fmt.Println(matched, err) 27 | matched, err = hyperscan.MatchReader(`bar.*`, s) 28 | fmt.Println(matched, err) 29 | matched, err = hyperscan.MatchReader(`a(b`, s) 30 | fmt.Println(matched, err) 31 | // Output: 32 | // true 33 | // false 34 | // false parse pattern, pattern `a(b`, Missing close parenthesis for group started at index 1. 35 | } 36 | -------------------------------------------------------------------------------- /hyperscan/example_compile_test.go: -------------------------------------------------------------------------------- 1 | package hyperscan_test 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | 7 | "github.com/flier/gohs/hyperscan" 8 | ) 9 | 10 | // This example demonstrates construct and match a pattern. 11 | func ExamplePattern() { 12 | p := hyperscan.NewPattern(`foo.*bar`, hyperscan.Caseless) 13 | fmt.Println(p) 14 | 15 | db, err := hyperscan.NewBlockDatabase(p) 16 | fmt.Println(err) 17 | 18 | found := db.MatchString("fooxyzbarbar") 19 | fmt.Println(found) 20 | 21 | // Output: 22 | // /foo.*bar/i 23 | // 24 | // true 25 | } 26 | 27 | // This example demonstrates parsing pattern with id and flags. 28 | func ExampleParsePattern() { 29 | p, err := hyperscan.ParsePattern("3:/foobar/i8") 30 | 31 | fmt.Println(err) 32 | fmt.Println(p.Id) 33 | fmt.Println(p.Expression) 34 | fmt.Println(p.Flags) 35 | 36 | // Output: 37 | // 38 | // 3 39 | // foobar 40 | // 8i 41 | } 42 | 43 | // This example demonstrates parsing patterns with comment. 44 | func ExampleParsePatterns() { 45 | patterns, err := hyperscan.ParsePatterns(strings.NewReader(` 46 | # empty line and comment will be skipped 47 | 48 | 1:/hatstand.*teakettle/s 49 | 2:/(hatstand|teakettle)/iH 50 | 3:/^.{10,20}hatstand/m 51 | `)) 52 | 53 | fmt.Println(err) 54 | 55 | for _, p := range patterns { 56 | fmt.Println(p) 57 | } 58 | 59 | // Output: 60 | // 61 | // 1:/hatstand.*teakettle/s 62 | // 2:/(hatstand|teakettle)/Hi 63 | // 3:/^.{10,20}hatstand/m 64 | } 65 | -------------------------------------------------------------------------------- /hyperscan/patterns.go: -------------------------------------------------------------------------------- 1 | package hyperscan 2 | 3 | const ( 4 | // FloatNumber for matching floating point numbers. 5 | FloatNumber = `(?:` + 6 | `[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?.)` 7 | 8 | // IPv4Address for matching IPv4 address. 9 | IPv4Address = `(?:` + 10 | `(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?\.){3}` + 11 | `(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))` 12 | 13 | // EmailAddress for matching email address. 14 | EmailAddress = `(?:` + 15 | `^[A-Za-z0-9](([_\.\-]?[a-zA-Z0-9]+)*)@` + 16 | `([A-Za-z0-9]+)(([\.\-]?[a-zA-Z0-9]+)*)\.([A-Za-z]{2,})$)` 17 | 18 | // CreditCard for matching credit card number. 19 | CreditCard = `(?:` + 20 | `4[0-9]{12}(?:[0-9]{3})?|` + // Visa 21 | `5[1-5][0-9]{14}|` + // MasterCard 22 | `3[47][0-9]{13}|` + // American Express 23 | `3(?:0[0-5]|[68][0-9])[0-9]{11}|` + // Diners Club 24 | `6(?:011|5[0-9]{2})[0-9]{12}|` + // Discover 25 | `(?:2131|1800|35\d{3})\d{11})` // JCB 26 | ) 27 | -------------------------------------------------------------------------------- /hyperscan/patterns_test.go: -------------------------------------------------------------------------------- 1 | package hyperscan_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | 8 | "github.com/flier/gohs/hyperscan" 9 | ) 10 | 11 | func TestFloatNumber(t *testing.T) { 12 | Convey("Given a compiled pattern", t, func() { 13 | db := hyperscan.MustCompile(hyperscan.FloatNumber) 14 | 15 | So(db, ShouldNotBeNil) 16 | }) 17 | } 18 | 19 | func TestIPv4Address(t *testing.T) { 20 | Convey("Given a compiled pattern", t, func() { 21 | db := hyperscan.MustCompile(hyperscan.IPv4Address) 22 | 23 | So(db, ShouldNotBeNil) 24 | }) 25 | } 26 | 27 | func TestEmailAddress(t *testing.T) { 28 | Convey("Given a compiled pattern", t, func() { 29 | db := hyperscan.MustCompile(hyperscan.EmailAddress) 30 | 31 | So(db, ShouldNotBeNil) 32 | }) 33 | } 34 | 35 | func TestCreditCard(t *testing.T) { 36 | Convey("Given a compiled pattern", t, func() { 37 | db := hyperscan.MustCompile(hyperscan.CreditCard) 38 | 39 | So(db, ShouldNotBeNil) 40 | }) 41 | } 42 | -------------------------------------------------------------------------------- /hyperscan/platform.go: -------------------------------------------------------------------------------- 1 | package hyperscan 2 | 3 | import "github.com/flier/gohs/internal/hs" 4 | 5 | type TuneFlag = hs.TuneFlag 6 | 7 | const ( 8 | // Generic indicates that the compiled database should not be tuned for any particular target platform. 9 | Generic TuneFlag = hs.Generic 10 | // SandyBridge indicates that the compiled database should be tuned for the Sandy Bridge microarchitecture. 11 | SandyBridge TuneFlag = hs.SandyBridge 12 | // IvyBridge indicates that the compiled database should be tuned for the Ivy Bridge microarchitecture. 13 | IvyBridge TuneFlag = hs.IvyBridge 14 | // Haswell indicates that the compiled database should be tuned for the Haswell microarchitecture. 15 | Haswell TuneFlag = hs.Haswell 16 | // Silvermont indicates that the compiled database should be tuned for the Silvermont microarchitecture. 17 | Silvermont TuneFlag = hs.Silvermont 18 | // Broadwell indicates that the compiled database should be tuned for the Broadwell microarchitecture. 19 | Broadwell TuneFlag = hs.Broadwell 20 | // Skylake indicates that the compiled database should be tuned for the Skylake microarchitecture. 21 | Skylake TuneFlag = hs.Skylake 22 | // SkylakeServer indicates that the compiled database should be tuned for the Skylake Server microarchitecture. 23 | SkylakeServer TuneFlag = hs.SkylakeServer 24 | // Goldmont indicates that the compiled database should be tuned for the Goldmont microarchitecture. 25 | Goldmont TuneFlag = hs.Goldmont 26 | ) 27 | 28 | // CpuFeature is the CPU feature support flags. 29 | type CpuFeature = hs.CpuFeature //nolint: golint,stylecheck,revive 30 | 31 | const ( 32 | // AVX2 is a CPU features flag indicates that the target platform supports AVX2 instructions. 33 | AVX2 CpuFeature = hs.AVX2 34 | // AVX512 is a CPU features flag indicates that the target platform supports AVX512 instructions, 35 | // specifically AVX-512BW. Using AVX512 implies the use of AVX2. 36 | AVX512 CpuFeature = hs.AVX512 37 | ) 38 | 39 | // Platform is a type containing information on the target platform. 40 | type Platform interface { 41 | // Information about the target platform which may be used to guide the optimisation process of the compile. 42 | Tune() TuneFlag 43 | 44 | // Relevant CPU features available on the target platform 45 | CpuFeatures() CpuFeature 46 | } 47 | 48 | // NewPlatform create a new platform information on the target platform. 49 | func NewPlatform(tune TuneFlag, cpu CpuFeature) Platform { return hs.NewPlatformInfo(tune, cpu) } 50 | 51 | // PopulatePlatform populates the platform information based on the current host. 52 | func PopulatePlatform() Platform { 53 | platform, _ := hs.PopulatePlatform() 54 | 55 | return platform 56 | } 57 | -------------------------------------------------------------------------------- /hyperscan/platform_test.go: -------------------------------------------------------------------------------- 1 | package hyperscan_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | 8 | "github.com/flier/gohs/hyperscan" 9 | ) 10 | 11 | func TestPlatform(t *testing.T) { 12 | Convey("Given a native platform", t, func() { 13 | p := hyperscan.PopulatePlatform() 14 | 15 | So(p, ShouldNotBeNil) 16 | So(p.Tune(), ShouldBeGreaterThanOrEqualTo, hyperscan.Generic) 17 | So(p.CpuFeatures(), ShouldBeGreaterThanOrEqualTo, 0) 18 | 19 | So(p, ShouldResemble, hyperscan.NewPlatform(p.Tune(), p.CpuFeatures())) 20 | }) 21 | } 22 | -------------------------------------------------------------------------------- /hyperscan/platform_v54.go: -------------------------------------------------------------------------------- 1 | //go:build hyperscan_v54 2 | // +build hyperscan_v54 3 | 4 | package hyperscan 5 | 6 | import "github.com/flier/gohs/internal/hs" 7 | 8 | const ( 9 | // AVX512VBMI is a CPU features flag indicates that the target platform 10 | // supports Intel(R) Advanced Vector Extensions 512 Vector Byte Manipulation Instructions (Intel(R) AVX512VBMI) 11 | AVX512VBMI CpuFeature = hs.AVX512VBMI 12 | ) 13 | 14 | const ( 15 | // Icelake indicates that the compiled database should be tuned for the Icelake microarchitecture. 16 | Icelake TuneFlag = hs.Icelake 17 | // IcelakeServer indicates that the compiled database should be tuned for the Icelake Server microarchitecture. 18 | IcelakeServer TuneFlag = hs.IcelakeServer 19 | ) 20 | -------------------------------------------------------------------------------- /hyperscan/runtime.go: -------------------------------------------------------------------------------- 1 | package hyperscan 2 | 3 | import ( 4 | "errors" 5 | 6 | "github.com/flier/gohs/internal/hs" 7 | ) 8 | 9 | // ErrTooManyMatches means too many matches. 10 | var ErrTooManyMatches = errors.New("too many matches") 11 | 12 | // MatchContext represents a match context. 13 | type MatchContext interface { 14 | Database() Database 15 | 16 | Scratch() Scratch 17 | 18 | UserData() interface{} 19 | } 20 | 21 | // MatchEvent indicates a match event. 22 | type MatchEvent interface { 23 | Id() uint 24 | 25 | From() uint64 26 | 27 | To() uint64 28 | 29 | Flags() ScanFlag 30 | } 31 | 32 | type ScanFlag = hs.ScanFlag 33 | 34 | // MatchHandler handles match events. 35 | type MatchHandler = hs.MatchEventHandler 36 | -------------------------------------------------------------------------------- /hyperscan/scratch.go: -------------------------------------------------------------------------------- 1 | package hyperscan 2 | 3 | import ( 4 | "runtime" 5 | 6 | "github.com/flier/gohs/internal/hs" 7 | ) 8 | 9 | // Scratch is a Hyperscan scratch space. 10 | type Scratch struct { 11 | s hs.Scratch 12 | } 13 | 14 | // NewScratch allocate a "scratch" space for use by Hyperscan. 15 | // This is required for runtime use, and one scratch space per thread, 16 | // or concurrent caller, is required. 17 | func NewScratch(db Database) (*Scratch, error) { 18 | s, err := hs.AllocScratch(db.(database).c()) 19 | if err != nil { 20 | return nil, err //nolint: wrapcheck 21 | } 22 | 23 | return &Scratch{s}, nil 24 | } 25 | 26 | // NewManagedScratch is a wrapper for NewScratch that sets 27 | // a finalizer on the Scratch instance so that memory is freed 28 | // once the object is no longer in use. 29 | func NewManagedScratch(db Database) (*Scratch, error) { 30 | s, err := NewScratch(db) 31 | if err != nil { 32 | return nil, err 33 | } 34 | 35 | runtime.SetFinalizer(s, func(scratch *Scratch) { 36 | _ = scratch.Free() 37 | }) 38 | return s, nil 39 | } 40 | 41 | // Size provides the size of the given scratch space. 42 | func (s *Scratch) Size() (int, error) { return hs.ScratchSize(s.s) } //nolint: wrapcheck 43 | 44 | // Realloc reallocate the scratch for another database. 45 | func (s *Scratch) Realloc(db Database) error { 46 | r, _ := db.(database) 47 | 48 | return hs.ReallocScratch(r.c(), &s.s) //nolint: wrapcheck 49 | } 50 | 51 | // Clone allocate a scratch space that is a clone of an existing scratch space. 52 | func (s *Scratch) Clone() (*Scratch, error) { 53 | cloned, err := hs.CloneScratch(s.s) 54 | if err != nil { 55 | return nil, err //nolint: wrapcheck 56 | } 57 | 58 | return &Scratch{cloned}, nil 59 | } 60 | 61 | // Free a scratch block previously allocated. 62 | func (s *Scratch) Free() error { return hs.FreeScratch(s.s) } //nolint: wrapcheck 63 | -------------------------------------------------------------------------------- /hyperscan/vectored.go: -------------------------------------------------------------------------------- 1 | package hyperscan 2 | 3 | import "github.com/flier/gohs/internal/hs" 4 | 5 | // VectoredScanner is the vectored regular expression scanner. 6 | type VectoredScanner interface { 7 | Scan(data [][]byte, scratch *Scratch, handler MatchHandler, context interface{}) error 8 | } 9 | 10 | // VectoredMatcher implements regular expression search. 11 | type VectoredMatcher interface{} 12 | 13 | // VectoredDatabase scan the target data that consists of a list of non-contiguous blocks 14 | // that are available all at once. 15 | type VectoredDatabase interface { 16 | Database 17 | VectoredScanner 18 | VectoredMatcher 19 | } 20 | 21 | type vectoredDatabase struct { 22 | *vectoredMatcher 23 | } 24 | 25 | func newVectoredDatabase(db hs.Database) *vectoredDatabase { 26 | return &vectoredDatabase{newVectoredMatcher(newVectoredScanner(newBaseDatabase(db)))} 27 | } 28 | 29 | type vectoredScanner struct { 30 | *baseDatabase 31 | } 32 | 33 | func newVectoredScanner(vdb *baseDatabase) *vectoredScanner { 34 | return &vectoredScanner{vdb} 35 | } 36 | 37 | func (vs *vectoredScanner) Scan(data [][]byte, s *Scratch, handler MatchHandler, context interface{}) (err error) { 38 | if s == nil { 39 | s, err = NewScratch(vs) 40 | 41 | if err != nil { 42 | return 43 | } 44 | 45 | defer func() { 46 | _ = s.Free() 47 | }() 48 | } 49 | 50 | return hs.ScanVector(vs.db, data, 0, s.s, handler, context) //nolint: wrapcheck 51 | } 52 | 53 | type vectoredMatcher struct { 54 | *vectoredScanner 55 | } 56 | 57 | func newVectoredMatcher(scanner *vectoredScanner) *vectoredMatcher { 58 | return &vectoredMatcher{vectoredScanner: scanner} 59 | } 60 | -------------------------------------------------------------------------------- /internal/ch/allocator_test.go: -------------------------------------------------------------------------------- 1 | package ch_test 2 | 3 | import ( 4 | "testing" 5 | "unsafe" 6 | 7 | . "github.com/smartystreets/goconvey/convey" 8 | 9 | "github.com/flier/gohs/internal/ch" 10 | "github.com/flier/gohs/internal/hs" 11 | ) 12 | 13 | type testAllocator struct { 14 | memoryUsed int 15 | memoryFreed []unsafe.Pointer 16 | } 17 | 18 | func (a *testAllocator) alloc(size uint) unsafe.Pointer { 19 | a.memoryUsed += int(size) 20 | 21 | return ch.AlignedAlloc(size) 22 | } 23 | 24 | func (a *testAllocator) free(ptr unsafe.Pointer) { 25 | a.memoryFreed = append(a.memoryFreed, ptr) 26 | 27 | ch.AlignedFree(ptr) 28 | } 29 | 30 | //nolint:funlen 31 | func TestAllocator(t *testing.T) { 32 | Convey("Given the host platform", t, func() { 33 | platform, err := hs.PopulatePlatform() 34 | 35 | So(platform, ShouldNotBeNil) 36 | So(err, ShouldBeNil) 37 | 38 | a := &testAllocator{} 39 | 40 | Convey("Then create a database with allocator", func() { 41 | So(ch.SetDatabaseAllocator(a.alloc, a.free), ShouldBeNil) 42 | 43 | db, err := ch.Compile("test", 0, ch.Groups, platform) 44 | 45 | So(db, ShouldNotBeNil) 46 | So(err, ShouldBeNil) 47 | 48 | Convey("Then get the database info with allocator", func() { 49 | So(ch.SetMiscAllocator(a.alloc, a.free), ShouldBeNil) 50 | 51 | s, err := ch.DatabaseInfo(db) 52 | So(err, ShouldBeNil) 53 | So(s, ShouldNotBeEmpty) 54 | 55 | So(a.memoryUsed, ShouldBeGreaterThanOrEqualTo, 12) 56 | 57 | So(ch.ClearMiscAllocator(), ShouldBeNil) 58 | }) 59 | 60 | Convey("Get the database size", func() { 61 | size, err := ch.DatabaseSize(db) 62 | 63 | So(a.memoryUsed, ShouldBeGreaterThanOrEqualTo, size) 64 | So(err, ShouldBeNil) 65 | }) 66 | 67 | Convey("Then create a scratch with allocator", func() { 68 | So(ch.SetScratchAllocator(a.alloc, a.free), ShouldBeNil) 69 | 70 | a.memoryUsed = 0 71 | 72 | s, err := ch.AllocScratch(db) 73 | 74 | So(s, ShouldNotBeNil) 75 | So(err, ShouldBeNil) 76 | 77 | Convey("Get the scratch size", func() { 78 | size, err := ch.ScratchSize(s) 79 | 80 | So(a.memoryUsed, ShouldBeGreaterThanOrEqualTo, size) 81 | So(err, ShouldBeNil) 82 | }) 83 | 84 | Convey("Then free scratch with allocator", func() { 85 | a.memoryFreed = nil 86 | 87 | So(ch.FreeScratch(s), ShouldBeNil) 88 | 89 | So(a.memoryFreed[len(a.memoryFreed)-1], ShouldEqual, unsafe.Pointer(s)) 90 | 91 | So(ch.ClearScratchAllocator(), ShouldBeNil) 92 | }) 93 | }) 94 | 95 | Convey("Then free database with allocator", func() { 96 | a.memoryFreed = nil 97 | 98 | So(ch.FreeDatabase(db), ShouldBeNil) 99 | 100 | So(a.memoryFreed, ShouldResemble, []unsafe.Pointer{unsafe.Pointer(db)}) 101 | 102 | So(ch.ClearDatabaseAllocator(), ShouldBeNil) 103 | }) 104 | }) 105 | }) 106 | } 107 | -------------------------------------------------------------------------------- /internal/ch/common.go: -------------------------------------------------------------------------------- 1 | package ch 2 | 3 | import ( 4 | "unsafe" 5 | ) 6 | 7 | // #include 8 | import "C" 9 | 10 | type Database *C.ch_database_t 11 | 12 | func FreeDatabase(db Database) (err error) { 13 | if ret := C.ch_free_database(db); ret != C.CH_SUCCESS { 14 | err = Error(ret) 15 | } 16 | 17 | return 18 | } 19 | 20 | func Version() string { 21 | return C.GoString(C.ch_version()) 22 | } 23 | 24 | func DatabaseSize(db Database) (n int, err error) { 25 | var size C.size_t 26 | 27 | if ret := C.ch_database_size(db, &size); ret != C.CH_SUCCESS { 28 | err = Error(ret) 29 | } else { 30 | n = int(size) 31 | } 32 | 33 | return 34 | } 35 | 36 | func DatabaseInfo(db Database) (s string, err error) { 37 | var info *C.char 38 | 39 | if ret := C.ch_database_info(db, &info); ret != C.HS_SUCCESS { 40 | err = Error(ret) 41 | } 42 | 43 | s = C.GoString(info) 44 | C.free(unsafe.Pointer(info)) 45 | 46 | return 47 | } 48 | -------------------------------------------------------------------------------- /internal/ch/common_test.go: -------------------------------------------------------------------------------- 1 | package ch_test 2 | 3 | import ( 4 | "regexp" 5 | "testing" 6 | 7 | . "github.com/smartystreets/goconvey/convey" 8 | 9 | "github.com/flier/gohs/internal/ch" 10 | ) 11 | 12 | func TestVersion(t *testing.T) { 13 | Convey("Given a Chimera version", t, func() { 14 | ver := ch.Version() 15 | 16 | So(ver, ShouldNotBeEmpty) 17 | 18 | matched, err := regexp.MatchString(`^\d\.\d\.\d.*`, ver) 19 | 20 | So(err, ShouldBeNil) 21 | So(matched, ShouldBeTrue) 22 | }) 23 | } 24 | -------------------------------------------------------------------------------- /internal/ch/compile_test.go: -------------------------------------------------------------------------------- 1 | package ch_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | 8 | "github.com/flier/gohs/chimera" 9 | "github.com/flier/gohs/internal/ch" 10 | "github.com/flier/gohs/internal/hs" 11 | ) 12 | 13 | func TestCompileAPI(t *testing.T) { 14 | Convey("Given a host platform", t, func() { 15 | platform, err := hs.PopulatePlatform() 16 | 17 | So(platform, ShouldNotBeNil) 18 | So(err, ShouldBeNil) 19 | 20 | Convey("Compile an empty expression", func() { 21 | db, err := ch.Compile("", 0, ch.Groups, platform) 22 | 23 | So(err, ShouldBeNil) 24 | So(db, ShouldNotBeNil) 25 | 26 | So(ch.FreeDatabase(db), ShouldBeNil) 27 | }) 28 | 29 | Convey("Compile multi expressions", func() { 30 | db, err := ch.CompileMulti(chimera.Patterns{ 31 | chimera.NewPattern(`^\w+`, 0), 32 | chimera.NewPattern(`\d+`, 0), 33 | chimera.NewPattern(`\s+`, 0), 34 | }, ch.Groups, platform) 35 | 36 | So(db, ShouldNotBeNil) 37 | So(err, ShouldBeNil) 38 | 39 | Convey("Get the database info", func() { 40 | _, err := ch.DatabaseInfo(db) 41 | 42 | So(err, ShouldBeNil) 43 | }) 44 | 45 | So(ch.FreeDatabase(db), ShouldBeNil) 46 | }) 47 | 48 | Convey("Compile multi expressions with extension", func() { 49 | db, err := ch.CompileExtMulti(chimera.Patterns{ 50 | chimera.NewPattern(`^\w+`, 0), 51 | chimera.NewPattern(`\d+`, 0), 52 | chimera.NewPattern(`\s+`, 0), 53 | }, ch.Groups, platform, 1, 1) 54 | 55 | So(db, ShouldNotBeNil) 56 | So(err, ShouldBeNil) 57 | 58 | Convey("Get the database info", func() { 59 | _, err := ch.DatabaseInfo(db) 60 | 61 | So(err, ShouldBeNil) 62 | }) 63 | 64 | So(ch.FreeDatabase(db), ShouldBeNil) 65 | }) 66 | }) 67 | } 68 | -------------------------------------------------------------------------------- /internal/ch/dummy.cxx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flier/gohs/9dd8ff12354342d63a6e036780f4b19c7ac9ce01/internal/ch/dummy.cxx -------------------------------------------------------------------------------- /internal/ch/error.go: -------------------------------------------------------------------------------- 1 | package ch 2 | 3 | // #include 4 | import "C" 5 | 6 | import "fmt" 7 | 8 | // Error represents an error. 9 | type Error C.ch_error_t 10 | 11 | const ( 12 | // ErrSuccess is the error returned if the engine completed normally. 13 | ErrSuccess Error = C.CH_SUCCESS 14 | // ErrInvalid is the error returned if a parameter passed to this function was invalid. 15 | ErrInvalid Error = C.CH_INVALID 16 | // ErrNoMemory is the error returned if a memory allocation failed. 17 | ErrNoMemory Error = C.CH_NOMEM 18 | // ErrScanTerminated is the error returned if the engine was terminated by callback. 19 | ErrScanTerminated Error = C.CH_SCAN_TERMINATED 20 | // ErrCompileError is the error returned if the pattern compiler failed. 21 | ErrCompileError Error = C.CH_COMPILER_ERROR 22 | // ErrDatabaseVersionError is the error returned if the given database was built for a different version of Hyperscan. 23 | ErrDatabaseVersionError Error = C.CH_DB_VERSION_ERROR 24 | // ErrDatabasePlatformError is the error returned if the given database was built for a different platform. 25 | ErrDatabasePlatformError Error = C.CH_DB_PLATFORM_ERROR 26 | // ErrDatabaseModeError is the error returned if the given database was built for a different mode of operation. 27 | ErrDatabaseModeError Error = C.CH_DB_MODE_ERROR 28 | // ErrBadAlign is the error returned if a parameter passed to this function was not correctly aligned. 29 | ErrBadAlign Error = C.CH_BAD_ALIGN 30 | // ErrBadAlloc is the error returned if the memory allocator did not correctly return memory suitably aligned. 31 | ErrBadAlloc Error = C.CH_BAD_ALLOC 32 | // ErrScratchInUse is the error returned if the scratch region was already in use. 33 | ErrScratchInUse Error = C.CH_SCRATCH_IN_USE 34 | ) 35 | 36 | var ErrorMessages = map[Error]string{ 37 | C.CH_SUCCESS: "The engine completed normally.", 38 | C.CH_INVALID: "A parameter passed to this function was invalid.", 39 | C.CH_NOMEM: "A memory allocation failed.", 40 | C.CH_SCAN_TERMINATED: "The engine was terminated by callback.", 41 | C.CH_COMPILER_ERROR: "The pattern compiler failed.", 42 | C.CH_DB_VERSION_ERROR: "The given database was built for a different version of Hyperscan.", 43 | C.CH_DB_PLATFORM_ERROR: "The given database was built for a different platform (i.e., CPU type).", 44 | C.CH_DB_MODE_ERROR: "The given database was built for a different mode of operation.", 45 | C.CH_BAD_ALIGN: "A parameter passed to this function was not correctly aligned.", 46 | C.CH_BAD_ALLOC: "The memory allocator did not correctly return aligned memory.", 47 | C.CH_SCRATCH_IN_USE: "The scratch region was already in use.", 48 | } 49 | 50 | func (e Error) Error() string { 51 | if msg, exists := ErrorMessages[e]; exists { 52 | return msg 53 | } 54 | 55 | return fmt.Sprintf("unexpected error, %d", int(C.ch_error_t(e))) 56 | } 57 | -------------------------------------------------------------------------------- /internal/ch/error_v54.go: -------------------------------------------------------------------------------- 1 | //go:build hyperscan_v54 2 | // +build hyperscan_v54 3 | 4 | package ch 5 | 6 | // #include 7 | import "C" 8 | 9 | // ErrUnknown is the unexpected internal error from Hyperscan. 10 | const ErrUnknownHSError Error = C.CH_UNKNOWN_HS_ERROR 11 | 12 | func init() { 13 | ErrorMessages[C.CH_UNKNOWN_HS_ERROR] = "Unexpected internal error from Hyperscan." 14 | } 15 | -------------------------------------------------------------------------------- /internal/ch/link.go: -------------------------------------------------------------------------------- 1 | package ch 2 | 3 | /* 4 | #cgo pkg-config: --static libch 5 | #cgo linux LDFLAGS: -lm -lstdc++ -lpcre 6 | #cgo darwin LDFLAGS: -lpcre 7 | */ 8 | import "C" 9 | -------------------------------------------------------------------------------- /internal/ch/runtime_test.go: -------------------------------------------------------------------------------- 1 | package ch_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | 8 | "github.com/flier/gohs/internal/ch" 9 | "github.com/flier/gohs/internal/hs" 10 | ) 11 | 12 | func TestBlockScan(t *testing.T) { 13 | Convey("Given a block database", t, func() { 14 | platform, err := hs.PopulatePlatform() 15 | 16 | So(platform, ShouldNotBeNil) 17 | So(err, ShouldBeNil) 18 | 19 | db, err := ch.Compile("test", 0, ch.Groups, platform) 20 | 21 | So(db, ShouldNotBeNil) 22 | So(err, ShouldBeNil) 23 | 24 | s, err := ch.AllocScratch(db) 25 | 26 | So(s, ShouldNotBeNil) 27 | So(err, ShouldBeNil) 28 | 29 | h := &ch.MatchRecorder{} 30 | 31 | Convey("Scan block with pattern", func() { 32 | So(ch.Scan(db, []byte("abctestdef"), 0, s, h.OnMatch, h.OnError, nil), ShouldBeNil) 33 | So(h.Events, ShouldResemble, []ch.MatchEvent{{0, 3, 7, 0, []*ch.Capture{{3, 7, []byte("test")}}}}) 34 | }) 35 | 36 | Convey("Scan block without pattern", func() { 37 | So(ch.Scan(db, []byte("abcdef"), 0, s, h.OnMatch, h.OnError, nil), ShouldBeNil) 38 | So(h.Events, ShouldBeEmpty) 39 | }) 40 | 41 | Convey("Scan block with multi pattern", func() { 42 | So(ch.Scan(db, []byte("abctestdeftest"), 0, s, h.OnMatch, h.OnError, nil), ShouldBeNil) 43 | So(h.Events, ShouldResemble, []ch.MatchEvent{ 44 | {0, 3, 7, 0, []*ch.Capture{{3, 7, []byte("test")}}}, 45 | {0, 10, 14, 0, []*ch.Capture{{10, 14, []byte("test")}}}, 46 | }) 47 | }) 48 | 49 | Convey("Scan block with multi pattern but terminated", func() { 50 | onMatch := func(id uint, from, to uint64, flags uint, captured []*ch.Capture, context interface{}) ch.Callback { 51 | return ch.Terminate 52 | } 53 | 54 | So(ch.Scan(db, []byte("abctestdeftest"), 0, s, onMatch, h.OnError, nil), ShouldEqual, ch.ErrScanTerminated) 55 | }) 56 | 57 | Convey("Scan empty buffers", func() { 58 | So(ch.Scan(db, nil, 0, s, h.OnMatch, h.OnError, nil), ShouldEqual, ch.ErrInvalid) 59 | So(ch.Scan(db, []byte(""), 0, s, h.OnMatch, h.OnError, nil), ShouldBeNil) 60 | }) 61 | 62 | So(ch.FreeScratch(s), ShouldBeNil) 63 | So(ch.FreeDatabase(db), ShouldBeNil) 64 | }) 65 | } 66 | -------------------------------------------------------------------------------- /internal/ch/scratch.go: -------------------------------------------------------------------------------- 1 | package ch 2 | 3 | // #include 4 | import "C" 5 | 6 | type Scratch *C.ch_scratch_t 7 | 8 | func AllocScratch(db Database) (Scratch, error) { 9 | var scratch *C.ch_scratch_t 10 | 11 | if ret := C.ch_alloc_scratch(db, &scratch); ret != C.CH_SUCCESS { 12 | return nil, Error(ret) 13 | } 14 | 15 | return scratch, nil 16 | } 17 | 18 | func ReallocScratch(db Database, scratch *Scratch) error { 19 | if ret := C.ch_alloc_scratch(db, (**C.struct_ch_scratch)(scratch)); ret != C.CH_SUCCESS { 20 | return Error(ret) 21 | } 22 | 23 | return nil 24 | } 25 | 26 | func CloneScratch(scratch Scratch) (Scratch, error) { 27 | var clone *C.ch_scratch_t 28 | 29 | if ret := C.ch_clone_scratch(scratch, &clone); ret != C.CH_SUCCESS { 30 | return nil, Error(ret) 31 | } 32 | 33 | return clone, nil 34 | } 35 | 36 | func ScratchSize(scratch Scratch) (int, error) { 37 | var size C.size_t 38 | 39 | if ret := C.ch_scratch_size(scratch, &size); ret != C.CH_SUCCESS { 40 | return 0, Error(ret) 41 | } 42 | 43 | return int(size), nil 44 | } 45 | 46 | func FreeScratch(scratch Scratch) error { 47 | if ret := C.ch_free_scratch(scratch); ret != C.CH_SUCCESS { 48 | return Error(ret) 49 | } 50 | 51 | return nil 52 | } 53 | -------------------------------------------------------------------------------- /internal/ch/scratch_test.go: -------------------------------------------------------------------------------- 1 | package ch_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | 8 | "github.com/flier/gohs/hyperscan" 9 | "github.com/flier/gohs/internal/ch" 10 | "github.com/flier/gohs/internal/hs" 11 | ) 12 | 13 | //nolint:funlen 14 | func TestScratch(t *testing.T) { 15 | Convey("Given a block database", t, func() { 16 | platform, err := hs.PopulatePlatform() 17 | 18 | So(platform, ShouldNotBeNil) 19 | So(err, ShouldBeNil) 20 | 21 | db, err := ch.Compile("test", 0, ch.Groups, platform) 22 | 23 | So(db, ShouldNotBeNil) 24 | So(err, ShouldBeNil) 25 | 26 | Convey("Allocate a scratch", func() { 27 | s, err := ch.AllocScratch(db) 28 | 29 | So(s, ShouldNotBeNil) 30 | So(err, ShouldBeNil) 31 | 32 | Convey("Get the scratch size", func() { 33 | size, err := ch.ScratchSize(s) 34 | 35 | So(size, ShouldBeGreaterThan, 1024) 36 | So(size, ShouldBeLessThan, 4096) 37 | So(err, ShouldBeNil) 38 | 39 | Convey("Clone the scratch", func() { 40 | s2, err := ch.CloneScratch(s) 41 | 42 | So(s2, ShouldNotBeNil) 43 | So(err, ShouldBeNil) 44 | 45 | Convey("Cloned scrash should have same size", func() { 46 | size2, err := ch.ScratchSize(s2) 47 | 48 | So(size2, ShouldEqual, size) 49 | So(err, ShouldBeNil) 50 | }) 51 | 52 | So(ch.FreeScratch(s2), ShouldBeNil) 53 | }) 54 | 55 | Convey("Reallocate the scratch with another database", func() { 56 | db2, err := ch.Compile(hyperscan.EmailAddress, 0, ch.Groups, platform) 57 | 58 | So(db, ShouldNotBeNil) 59 | So(err, ShouldBeNil) 60 | 61 | So(ch.ReallocScratch(db2, &s), ShouldBeNil) 62 | 63 | size2, err := ch.ScratchSize(s) 64 | 65 | So(size2, ShouldBeGreaterThan, size) 66 | So(err, ShouldBeNil) 67 | 68 | So(ch.FreeDatabase(db2), ShouldBeNil) 69 | }) 70 | }) 71 | 72 | So(ch.FreeScratch(s), ShouldBeNil) 73 | }) 74 | 75 | So(ch.FreeDatabase(db), ShouldBeNil) 76 | }) 77 | } 78 | -------------------------------------------------------------------------------- /internal/hs/compile_v5.go: -------------------------------------------------------------------------------- 1 | //go:build !hyperscan_v4 2 | // +build !hyperscan_v4 3 | 4 | package hs 5 | 6 | /* 7 | #include 8 | */ 9 | import "C" 10 | 11 | const ( 12 | // Combination represents logical combination. 13 | Combination CompileFlag = C.HS_FLAG_COMBINATION 14 | // Quiet represents don't do any match reporting. 15 | Quiet CompileFlag = C.HS_FLAG_QUIET 16 | ) 17 | 18 | func init() { 19 | CompileFlags['C'] = Combination 20 | CompileFlags['Q'] = Quiet 21 | } 22 | -------------------------------------------------------------------------------- /internal/hs/compile_v54.go: -------------------------------------------------------------------------------- 1 | //go:build hyperscan_v54 2 | // +build hyperscan_v54 3 | 4 | package hs 5 | 6 | /* 7 | #include 8 | */ 9 | import "C" 10 | 11 | const ( 12 | // AVX512VBMI is a CPU features flag indicates that the target platform 13 | // supports Intel(R) Advanced Vector Extensions 512 Vector Byte Manipulation Instructions (Intel(R) AVX512VBMI) 14 | AVX512VBMI CpuFeature = C.HS_CPU_FEATURES_AVX512VBMI 15 | ) 16 | 17 | const ( 18 | // Icelake indicates that the compiled database should be tuned for the Icelake microarchitecture. 19 | Icelake TuneFlag = C.HS_TUNE_FAMILY_ICL 20 | // IcelakeServer indicates that the compiled database should be tuned for the Icelake Server microarchitecture. 21 | IcelakeServer TuneFlag = C.HS_TUNE_FAMILY_ICX 22 | ) 23 | -------------------------------------------------------------------------------- /internal/hs/dummy.cxx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flier/gohs/9dd8ff12354342d63a6e036780f4b19c7ac9ce01/internal/hs/dummy.cxx -------------------------------------------------------------------------------- /internal/hs/error_v5.go: -------------------------------------------------------------------------------- 1 | //go:build !hyperscan_v4 2 | // +build !hyperscan_v4 3 | 4 | package hs 5 | 6 | /* 7 | #include 8 | */ 9 | import "C" 10 | 11 | const ( 12 | // ErrUnknown is an unexpected internal error. 13 | ErrUnknown Error = C.HS_UNKNOWN_ERROR 14 | ) 15 | 16 | func init() { 17 | errorMessages[C.HS_UNKNOWN_ERROR] = "Unexpected internal error." 18 | } 19 | -------------------------------------------------------------------------------- /internal/hs/link.go: -------------------------------------------------------------------------------- 1 | package hs 2 | 3 | /* 4 | #cgo pkg-config: libhs 5 | #cgo linux LDFLAGS: -lm -lstdc++ 6 | */ 7 | import "C" 8 | -------------------------------------------------------------------------------- /internal/hs/scratch.go: -------------------------------------------------------------------------------- 1 | package hs 2 | 3 | // #include 4 | import "C" 5 | 6 | type Scratch *C.hs_scratch_t 7 | 8 | func AllocScratch(db Database) (Scratch, error) { 9 | var scratch *C.hs_scratch_t 10 | 11 | if ret := C.hs_alloc_scratch(db, &scratch); ret != C.HS_SUCCESS { 12 | return nil, Error(ret) 13 | } 14 | 15 | return scratch, nil 16 | } 17 | 18 | func ReallocScratch(db Database, scratch *Scratch) error { 19 | if ret := C.hs_alloc_scratch(db, (**C.struct_hs_scratch)(scratch)); ret != C.HS_SUCCESS { 20 | return Error(ret) 21 | } 22 | 23 | return nil 24 | } 25 | 26 | func CloneScratch(scratch Scratch) (Scratch, error) { 27 | var clone *C.hs_scratch_t 28 | 29 | if ret := C.hs_clone_scratch(scratch, &clone); ret != C.HS_SUCCESS { 30 | return nil, Error(ret) 31 | } 32 | 33 | return clone, nil 34 | } 35 | 36 | func ScratchSize(scratch Scratch) (int, error) { 37 | var size C.size_t 38 | 39 | if ret := C.hs_scratch_size(scratch, &size); ret != C.HS_SUCCESS { 40 | return 0, Error(ret) 41 | } 42 | 43 | return int(size), nil 44 | } 45 | 46 | func FreeScratch(scratch Scratch) error { 47 | if ret := C.hs_free_scratch(scratch); ret != C.HS_SUCCESS { 48 | return Error(ret) 49 | } 50 | 51 | return nil 52 | } 53 | -------------------------------------------------------------------------------- /internal/hs/scratch_test.go: -------------------------------------------------------------------------------- 1 | package hs_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | 8 | "github.com/flier/gohs/hyperscan" 9 | "github.com/flier/gohs/internal/hs" 10 | ) 11 | 12 | //nolint:funlen 13 | func TestScratch(t *testing.T) { 14 | Convey("Given a block database", t, func() { 15 | platform, err := hs.PopulatePlatform() 16 | 17 | So(platform, ShouldNotBeNil) 18 | So(err, ShouldBeNil) 19 | 20 | db, err := hs.Compile("test", 0, hs.BlockMode, platform) 21 | 22 | So(db, ShouldNotBeNil) 23 | So(err, ShouldBeNil) 24 | 25 | Convey("Allocate a scratch", func() { 26 | s, err := hs.AllocScratch(db) 27 | 28 | So(s, ShouldNotBeNil) 29 | So(err, ShouldBeNil) 30 | 31 | Convey("Get the scratch size", func() { 32 | size, err := hs.ScratchSize(s) 33 | 34 | So(size, ShouldBeGreaterThan, 1024) 35 | So(size, ShouldBeLessThan, 4096) 36 | So(err, ShouldBeNil) 37 | 38 | Convey("Clone the scratch", func() { 39 | s2, err := hs.CloneScratch(s) 40 | 41 | So(s2, ShouldNotBeNil) 42 | So(err, ShouldBeNil) 43 | 44 | Convey("Cloned scrash should have same size", func() { 45 | size2, err := hs.ScratchSize(s2) 46 | 47 | So(size2, ShouldEqual, size) 48 | So(err, ShouldBeNil) 49 | }) 50 | 51 | So(hs.FreeScratch(s2), ShouldBeNil) 52 | }) 53 | 54 | Convey("Reallocate the scratch with another database", func() { 55 | db2, err := hs.Compile(hyperscan.EmailAddress, 0, hyperscan.BlockMode, platform) 56 | 57 | So(db, ShouldNotBeNil) 58 | So(err, ShouldBeNil) 59 | 60 | So(hs.ReallocScratch(db2, &s), ShouldBeNil) 61 | 62 | size2, err := hs.ScratchSize(s) 63 | 64 | So(size2, ShouldBeGreaterThan, size) 65 | So(err, ShouldBeNil) 66 | 67 | So(hs.FreeDatabase(db2), ShouldBeNil) 68 | }) 69 | }) 70 | 71 | So(hs.FreeScratch(s), ShouldBeNil) 72 | }) 73 | 74 | So(hs.FreeDatabase(db), ShouldBeNil) 75 | }) 76 | } 77 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | #* 24 | *~ 25 | 26 | # examples binaries 27 | examples/synscan/synscan 28 | examples/pfdump/pfdump 29 | examples/pcapdump/pcapdump 30 | examples/httpassembly/httpassembly 31 | examples/statsassembly/statsassembly 32 | examples/arpscan/arpscan 33 | examples/bidirectional/bidirectional 34 | examples/bytediff/bytediff 35 | examples/reassemblydump/reassemblydump 36 | layers/gen 37 | macs/gen 38 | pcap/pcap_tester 39 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/.travis.gofmt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd "$(dirname $0)" 4 | if [ -n "$(go fmt ./...)" ]; then 5 | echo "Go code is not formatted, run 'go fmt github.com/google/stenographer/...'" >&2 6 | exit 1 7 | fi 8 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/.travis.golint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd "$(dirname $0)" 4 | 5 | go get golang.org/x/lint/golint 6 | DIRS=". tcpassembly tcpassembly/tcpreader ip4defrag reassembly macs pcapgo pcap afpacket pfring routing defrag/lcmdefrag" 7 | # Add subdirectories here as we clean up golint on each. 8 | for subdir in $DIRS; do 9 | pushd $subdir 10 | if golint | 11 | grep -v CannotSetRFMon | # pcap exported error name 12 | grep -v DataLost | # tcpassembly/tcpreader exported error name 13 | grep .; then 14 | exit 1 15 | fi 16 | popd 17 | done 18 | 19 | pushd layers 20 | for file in *.go; do 21 | if cat .lint_blacklist | grep -q $file; then 22 | echo "Skipping lint of $file due to .lint_blacklist" 23 | elif golint $file | grep .; then 24 | echo "Lint error in file $file" 25 | exit 1 26 | fi 27 | done 28 | popd 29 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/.travis.govet.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cd "$(dirname $0)" 4 | DIRS=". layers pcap pcapgo tcpassembly tcpassembly/tcpreader routing ip4defrag bytediff macs defrag/lcmdefrag" 5 | set -e 6 | for subdir in $DIRS; do 7 | pushd $subdir 8 | go vet 9 | popd 10 | done 11 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/.travis.install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ev 4 | 5 | go get github.com/google/gopacket 6 | go get github.com/google/gopacket/layers 7 | go get github.com/google/gopacket/tcpassembly 8 | go get github.com/google/gopacket/reassembly 9 | go get github.com/google/gopacket/pcapgo 10 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/.travis.script.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -ev 4 | 5 | go test github.com/google/gopacket 6 | go test github.com/google/gopacket/layers 7 | go test github.com/google/gopacket/tcpassembly 8 | go test github.com/google/gopacket/reassembly 9 | go test github.com/google/gopacket/pcapgo 10 | go test github.com/google/gopacket/pcap 11 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.11.x 4 | - 1.12.x 5 | - 1.13.x 6 | - master 7 | 8 | addons: 9 | apt: 10 | packages: 11 | libpcap-dev 12 | 13 | # use modules except for older versions (see below) 14 | install: true 15 | 16 | env: 17 | - GO111MODULE=on 18 | 19 | script: ./.travis.script.sh 20 | 21 | matrix: 22 | fast_finish: true 23 | allow_failures: 24 | - go: master 25 | 26 | jobs: 27 | include: 28 | - go: 1.5.x 29 | install: ./.travis.install.sh 30 | - go: 1.6.x 31 | install: ./.travis.install.sh 32 | - go: 1.7.x 33 | install: ./.travis.install.sh 34 | - go: 1.8.x 35 | install: ./.travis.install.sh 36 | - go: 1.9.x 37 | install: ./.travis.install.sh 38 | - go: 1.10.x 39 | install: ./.travis.install.sh 40 | - os: osx 41 | go: 1.x 42 | # windows doesn't work on travis (package installation just hangs and then errors out) 43 | # - os: windows 44 | # go: 1.x 45 | # # We don't need nmap - but that's the only way to get npcap: 46 | # before_install: choco install npcap --version 0.86 -y 47 | - stage: style 48 | name: "fmt/vet/lint" 49 | go: 1.x 50 | script: 51 | - ./.travis.gofmt.sh 52 | - ./.travis.govet.sh 53 | - ./.travis.golint.sh 54 | 55 | stages: 56 | - style 57 | - test 58 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/AUTHORS: -------------------------------------------------------------------------------- 1 | AUTHORS AND MAINTAINERS: 2 | 3 | MAIN DEVELOPERS: 4 | Graeme Connell 5 | 6 | AUTHORS: 7 | Nigel Tao 8 | Cole Mickens 9 | Ben Daglish 10 | Luis Martinez 11 | Remco Verhoef 12 | Hiroaki Kawai 13 | Lukas Lueg 14 | Laurent Hausermann 15 | Bill Green 16 | Christian Mäder 17 | Gernot Vormayr 18 | Vitor Garcia Graveto 19 | Elias Chavarria Reyes 20 | Daniel Rittweiler 21 | 22 | CONTRIBUTORS: 23 | Attila Oláh 24 | Vittus Mikiassen 25 | Matthias Radestock 26 | Matthew Sackman 27 | Loic Prylli 28 | Alexandre Fiori 29 | Adrian Tam 30 | Satoshi Matsumoto 31 | David Stainton 32 | Jesse Ward 33 | Kane Mathers 34 | Jose Selvi 35 | Yerden Zhumabekov 36 | Jensen Hwa 37 | 38 | ----------------------------------------------- 39 | FORKED FROM github.com/akrennmair/gopcap 40 | ALL THE FOLLOWING ARE FOR THAT PROJECT 41 | 42 | MAIN DEVELOPERS: 43 | Andreas Krennmair 44 | 45 | CONTRIBUTORS: 46 | Andrea Nall 47 | Daniel Arndt 48 | Dustin Sallings 49 | Graeme Connell 50 | Guillaume Savary 51 | Mark Smith 52 | Miek Gieben 53 | Mike Bell 54 | Trevor Strohman 55 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Google, Inc. All rights reserved. 2 | Copyright (c) 2009-2011 Andreas Krennmair. All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are 6 | met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | * Redistributions in binary form must reproduce the above 11 | copyright notice, this list of conditions and the following disclaimer 12 | in the documentation and/or other materials provided with the 13 | distribution. 14 | * Neither the name of Andreas Krennmair, Google, nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/README.md: -------------------------------------------------------------------------------- 1 | # GoPacket 2 | 3 | This library provides packet decoding capabilities for Go. 4 | See [godoc](https://godoc.org/github.com/google/gopacket) for more details. 5 | 6 | [![Build Status](https://travis-ci.org/google/gopacket.svg?branch=master)](https://travis-ci.org/google/gopacket) 7 | [![GoDoc](https://godoc.org/github.com/google/gopacket?status.svg)](https://godoc.org/github.com/google/gopacket) 8 | 9 | Minimum Go version required is 1.5 except for pcapgo/EthernetHandle, afpacket, and bsdbpf which need at least 1.9 due to x/sys/unix dependencies. 10 | 11 | Originally forked from the gopcap project written by Andreas 12 | Krennmair (http://github.com/akrennmair/gopcap). 13 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/layers/.lint_blacklist: -------------------------------------------------------------------------------- 1 | dot11.go 2 | eap.go 3 | endpoints.go 4 | enums_generated.go 5 | enums.go 6 | ethernet.go 7 | geneve.go 8 | icmp4.go 9 | icmp6.go 10 | igmp.go 11 | ip4.go 12 | ip6.go 13 | layertypes.go 14 | linux_sll.go 15 | llc.go 16 | lldp.go 17 | mpls.go 18 | ndp.go 19 | ntp.go 20 | ospf.go 21 | pflog.go 22 | pppoe.go 23 | prism.go 24 | radiotap.go 25 | rudp.go 26 | sctp.go 27 | sflow.go 28 | tcp.go 29 | tcpip.go 30 | tls.go 31 | tls_alert.go 32 | tls_appdata.go 33 | tls_cipherspec.go 34 | tls_hanshake.go 35 | tls_test.go 36 | udp.go 37 | udplite.go 38 | usb.go 39 | vrrp.go 40 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/layers/base.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google, Inc. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. 6 | 7 | package layers 8 | 9 | import ( 10 | "github.com/google/gopacket" 11 | ) 12 | 13 | // BaseLayer is a convenience struct which implements the LayerData and 14 | // LayerPayload functions of the Layer interface. 15 | type BaseLayer struct { 16 | // Contents is the set of bytes that make up this layer. IE: for an 17 | // Ethernet packet, this would be the set of bytes making up the 18 | // Ethernet frame. 19 | Contents []byte 20 | // Payload is the set of bytes contained by (but not part of) this 21 | // Layer. Again, to take Ethernet as an example, this would be the 22 | // set of bytes encapsulated by the Ethernet protocol. 23 | Payload []byte 24 | } 25 | 26 | // LayerContents returns the bytes of the packet layer. 27 | func (b *BaseLayer) LayerContents() []byte { return b.Contents } 28 | 29 | // LayerPayload returns the bytes contained within the packet layer. 30 | func (b *BaseLayer) LayerPayload() []byte { return b.Payload } 31 | 32 | type layerDecodingLayer interface { 33 | gopacket.Layer 34 | DecodeFromBytes([]byte, gopacket.DecodeFeedback) error 35 | NextLayerType() gopacket.LayerType 36 | } 37 | 38 | func decodingLayerDecoder(d layerDecodingLayer, data []byte, p gopacket.PacketBuilder) error { 39 | err := d.DecodeFromBytes(data, p) 40 | if err != nil { 41 | return err 42 | } 43 | p.AddLayer(d) 44 | next := d.NextLayerType() 45 | if next == gopacket.LayerTypeZero { 46 | return nil 47 | } 48 | return p.NextDecoder(next) 49 | } 50 | 51 | // hacky way to zero out memory... there must be a better way? 52 | var lotsOfZeros [1024]byte 53 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/layers/dot1q.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google, Inc. All rights reserved. 2 | // Copyright 2009-2011 Andreas Krennmair. All rights reserved. 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the LICENSE file in the root of the source 6 | // tree. 7 | 8 | package layers 9 | 10 | import ( 11 | "encoding/binary" 12 | "fmt" 13 | "github.com/google/gopacket" 14 | ) 15 | 16 | // Dot1Q is the packet layer for 802.1Q VLAN headers. 17 | type Dot1Q struct { 18 | BaseLayer 19 | Priority uint8 20 | DropEligible bool 21 | VLANIdentifier uint16 22 | Type EthernetType 23 | } 24 | 25 | // LayerType returns gopacket.LayerTypeDot1Q 26 | func (d *Dot1Q) LayerType() gopacket.LayerType { return LayerTypeDot1Q } 27 | 28 | // DecodeFromBytes decodes the given bytes into this layer. 29 | func (d *Dot1Q) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 30 | if len(data) < 4 { 31 | df.SetTruncated() 32 | return fmt.Errorf("802.1Q tag length %d too short", len(data)) 33 | } 34 | d.Priority = (data[0] & 0xE0) >> 5 35 | d.DropEligible = data[0]&0x10 != 0 36 | d.VLANIdentifier = binary.BigEndian.Uint16(data[:2]) & 0x0FFF 37 | d.Type = EthernetType(binary.BigEndian.Uint16(data[2:4])) 38 | d.BaseLayer = BaseLayer{Contents: data[:4], Payload: data[4:]} 39 | return nil 40 | } 41 | 42 | // CanDecode returns the set of layer types that this DecodingLayer can decode. 43 | func (d *Dot1Q) CanDecode() gopacket.LayerClass { 44 | return LayerTypeDot1Q 45 | } 46 | 47 | // NextLayerType returns the layer type contained by this DecodingLayer. 48 | func (d *Dot1Q) NextLayerType() gopacket.LayerType { 49 | return d.Type.LayerType() 50 | } 51 | 52 | func decodeDot1Q(data []byte, p gopacket.PacketBuilder) error { 53 | d := &Dot1Q{} 54 | return decodingLayerDecoder(d, data, p) 55 | } 56 | 57 | // SerializeTo writes the serialized form of this layer into the 58 | // SerializationBuffer, implementing gopacket.SerializableLayer. 59 | // See the docs for gopacket.SerializableLayer for more info. 60 | func (d *Dot1Q) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { 61 | bytes, err := b.PrependBytes(4) 62 | if err != nil { 63 | return err 64 | } 65 | if d.VLANIdentifier > 0xFFF { 66 | return fmt.Errorf("vlan identifier %v is too high", d.VLANIdentifier) 67 | } 68 | firstBytes := uint16(d.Priority)<<13 | d.VLANIdentifier 69 | if d.DropEligible { 70 | firstBytes |= 0x1000 71 | } 72 | binary.BigEndian.PutUint16(bytes, firstBytes) 73 | binary.BigEndian.PutUint16(bytes[2:], uint16(d.Type)) 74 | return nil 75 | } 76 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/layers/etherip.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google, Inc. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. 6 | 7 | package layers 8 | 9 | import ( 10 | "encoding/binary" 11 | "github.com/google/gopacket" 12 | ) 13 | 14 | // EtherIP is the struct for storing RFC 3378 EtherIP packet headers. 15 | type EtherIP struct { 16 | BaseLayer 17 | Version uint8 18 | Reserved uint16 19 | } 20 | 21 | // LayerType returns gopacket.LayerTypeEtherIP. 22 | func (e *EtherIP) LayerType() gopacket.LayerType { return LayerTypeEtherIP } 23 | 24 | // DecodeFromBytes decodes the given bytes into this layer. 25 | func (e *EtherIP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 26 | e.Version = data[0] >> 4 27 | e.Reserved = binary.BigEndian.Uint16(data[:2]) & 0x0fff 28 | e.BaseLayer = BaseLayer{data[:2], data[2:]} 29 | return nil 30 | } 31 | 32 | // CanDecode returns the set of layer types that this DecodingLayer can decode. 33 | func (e *EtherIP) CanDecode() gopacket.LayerClass { 34 | return LayerTypeEtherIP 35 | } 36 | 37 | // NextLayerType returns the layer type contained by this DecodingLayer. 38 | func (e *EtherIP) NextLayerType() gopacket.LayerType { 39 | return LayerTypeEthernet 40 | } 41 | 42 | func decodeEtherIP(data []byte, p gopacket.PacketBuilder) error { 43 | e := &EtherIP{} 44 | return decodingLayerDecoder(e, data, p) 45 | } 46 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/layers/fddi.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google, Inc. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. 6 | 7 | package layers 8 | 9 | import ( 10 | "github.com/google/gopacket" 11 | "net" 12 | ) 13 | 14 | // FDDI contains the header for FDDI frames. 15 | type FDDI struct { 16 | BaseLayer 17 | FrameControl FDDIFrameControl 18 | Priority uint8 19 | SrcMAC, DstMAC net.HardwareAddr 20 | } 21 | 22 | // LayerType returns LayerTypeFDDI. 23 | func (f *FDDI) LayerType() gopacket.LayerType { return LayerTypeFDDI } 24 | 25 | // LinkFlow returns a new flow of type EndpointMAC. 26 | func (f *FDDI) LinkFlow() gopacket.Flow { 27 | return gopacket.NewFlow(EndpointMAC, f.SrcMAC, f.DstMAC) 28 | } 29 | 30 | func decodeFDDI(data []byte, p gopacket.PacketBuilder) error { 31 | f := &FDDI{ 32 | FrameControl: FDDIFrameControl(data[0] & 0xF8), 33 | Priority: data[0] & 0x07, 34 | SrcMAC: net.HardwareAddr(data[1:7]), 35 | DstMAC: net.HardwareAddr(data[7:13]), 36 | BaseLayer: BaseLayer{data[:13], data[13:]}, 37 | } 38 | p.SetLinkLayer(f) 39 | p.AddLayer(f) 40 | return p.NextDecoder(f.FrameControl) 41 | } 42 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/layers/fuzz_layer.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The GoPacket Authors. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license that can be found 4 | // in the LICENSE file in the root of the source tree. 5 | 6 | package layers 7 | 8 | import ( 9 | "encoding/binary" 10 | 11 | "github.com/google/gopacket" 12 | ) 13 | 14 | // FuzzLayer is a fuzz target for the layers package of gopacket 15 | // A fuzz target is a function processing a binary blob (byte slice) 16 | // The process here is to interpret this data as a packet, and print the layers contents. 17 | // The decoding options and the starting layer are encoded in the first bytes. 18 | // The function returns 1 if this is a valid packet (no error layer) 19 | func FuzzLayer(data []byte) int { 20 | if len(data) < 3 { 21 | return 0 22 | } 23 | // use the first two bytes to choose the top level layer 24 | startLayer := binary.BigEndian.Uint16(data[:2]) 25 | var fuzzOpts = gopacket.DecodeOptions{ 26 | Lazy: data[2]&0x1 != 0, 27 | NoCopy: data[2]&0x2 != 0, 28 | SkipDecodeRecovery: data[2]&0x4 != 0, 29 | DecodeStreamsAsDatagrams: data[2]&0x8 != 0, 30 | } 31 | p := gopacket.NewPacket(data[3:], gopacket.LayerType(startLayer), fuzzOpts) 32 | for _, l := range p.Layers() { 33 | gopacket.LayerString(l) 34 | } 35 | if p.ErrorLayer() != nil { 36 | return 0 37 | } 38 | return 1 39 | } 40 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/layers/gen_linted.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | for i in *.go; do golint $i | grep -q . || echo $i; done > .linted 4 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/layers/ipsec.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google, Inc. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. 6 | 7 | package layers 8 | 9 | import ( 10 | "encoding/binary" 11 | "errors" 12 | "github.com/google/gopacket" 13 | ) 14 | 15 | // IPSecAH is the authentication header for IPv4/6 defined in 16 | // http://tools.ietf.org/html/rfc2402 17 | type IPSecAH struct { 18 | // While the auth header can be used for both IPv4 and v6, its format is that of 19 | // an IPv6 extension (NextHeader, PayloadLength, etc...), so we use ipv6ExtensionBase 20 | // to build it. 21 | ipv6ExtensionBase 22 | Reserved uint16 23 | SPI, Seq uint32 24 | AuthenticationData []byte 25 | } 26 | 27 | // LayerType returns LayerTypeIPSecAH. 28 | func (i *IPSecAH) LayerType() gopacket.LayerType { return LayerTypeIPSecAH } 29 | 30 | func decodeIPSecAH(data []byte, p gopacket.PacketBuilder) error { 31 | if len(data) < 12 { 32 | p.SetTruncated() 33 | return errors.New("IPSec AH packet less than 12 bytes") 34 | } 35 | i := &IPSecAH{ 36 | ipv6ExtensionBase: ipv6ExtensionBase{ 37 | NextHeader: IPProtocol(data[0]), 38 | HeaderLength: data[1], 39 | }, 40 | Reserved: binary.BigEndian.Uint16(data[2:4]), 41 | SPI: binary.BigEndian.Uint32(data[4:8]), 42 | Seq: binary.BigEndian.Uint32(data[8:12]), 43 | } 44 | i.ActualLength = (int(i.HeaderLength) + 2) * 4 45 | if len(data) < i.ActualLength { 46 | p.SetTruncated() 47 | return errors.New("Truncated AH packet < ActualLength") 48 | } 49 | i.AuthenticationData = data[12:i.ActualLength] 50 | i.Contents = data[:i.ActualLength] 51 | i.Payload = data[i.ActualLength:] 52 | p.AddLayer(i) 53 | return p.NextDecoder(i.NextHeader) 54 | } 55 | 56 | // IPSecESP is the encapsulating security payload defined in 57 | // http://tools.ietf.org/html/rfc2406 58 | type IPSecESP struct { 59 | BaseLayer 60 | SPI, Seq uint32 61 | // Encrypted contains the encrypted set of bytes sent in an ESP 62 | Encrypted []byte 63 | } 64 | 65 | // LayerType returns LayerTypeIPSecESP. 66 | func (i *IPSecESP) LayerType() gopacket.LayerType { return LayerTypeIPSecESP } 67 | 68 | func decodeIPSecESP(data []byte, p gopacket.PacketBuilder) error { 69 | i := &IPSecESP{ 70 | BaseLayer: BaseLayer{data, nil}, 71 | SPI: binary.BigEndian.Uint32(data[:4]), 72 | Seq: binary.BigEndian.Uint32(data[4:8]), 73 | Encrypted: data[8:], 74 | } 75 | p.AddLayer(i) 76 | return nil 77 | } 78 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/layers/loopback.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google, Inc. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. 6 | 7 | package layers 8 | 9 | import ( 10 | "encoding/binary" 11 | "errors" 12 | "fmt" 13 | 14 | "github.com/google/gopacket" 15 | ) 16 | 17 | // Loopback contains the header for loopback encapsulation. This header is 18 | // used by both BSD and OpenBSD style loopback decoding (pcap's DLT_NULL 19 | // and DLT_LOOP, respectively). 20 | type Loopback struct { 21 | BaseLayer 22 | Family ProtocolFamily 23 | } 24 | 25 | // LayerType returns LayerTypeLoopback. 26 | func (l *Loopback) LayerType() gopacket.LayerType { return LayerTypeLoopback } 27 | 28 | // DecodeFromBytes decodes the given bytes into this layer. 29 | func (l *Loopback) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 30 | if len(data) < 4 { 31 | return errors.New("Loopback packet too small") 32 | } 33 | 34 | // The protocol could be either big-endian or little-endian, we're 35 | // not sure. But we're PRETTY sure that the value is less than 36 | // 256, so we can check the first two bytes. 37 | var prot uint32 38 | if data[0] == 0 && data[1] == 0 { 39 | prot = binary.BigEndian.Uint32(data[:4]) 40 | } else { 41 | prot = binary.LittleEndian.Uint32(data[:4]) 42 | } 43 | if prot > 0xFF { 44 | return fmt.Errorf("Invalid loopback protocol %q", data[:4]) 45 | } 46 | 47 | l.Family = ProtocolFamily(prot) 48 | l.BaseLayer = BaseLayer{data[:4], data[4:]} 49 | return nil 50 | } 51 | 52 | // CanDecode returns the set of layer types that this DecodingLayer can decode. 53 | func (l *Loopback) CanDecode() gopacket.LayerClass { 54 | return LayerTypeLoopback 55 | } 56 | 57 | // NextLayerType returns the layer type contained by this DecodingLayer. 58 | func (l *Loopback) NextLayerType() gopacket.LayerType { 59 | return l.Family.LayerType() 60 | } 61 | 62 | // SerializeTo writes the serialized form of this layer into the 63 | // SerializationBuffer, implementing gopacket.SerializableLayer. 64 | func (l *Loopback) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { 65 | bytes, err := b.PrependBytes(4) 66 | if err != nil { 67 | return err 68 | } 69 | binary.LittleEndian.PutUint32(bytes, uint32(l.Family)) 70 | return nil 71 | } 72 | 73 | func decodeLoopback(data []byte, p gopacket.PacketBuilder) error { 74 | l := Loopback{} 75 | if err := l.DecodeFromBytes(data, gopacket.NilDecodeFeedback); err != nil { 76 | return err 77 | } 78 | p.AddLayer(&l) 79 | return p.NextDecoder(l.Family) 80 | } 81 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/layers/pflog.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google, Inc. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. 6 | 7 | package layers 8 | 9 | import ( 10 | "encoding/binary" 11 | "errors" 12 | "fmt" 13 | 14 | "github.com/google/gopacket" 15 | ) 16 | 17 | type PFDirection uint8 18 | 19 | const ( 20 | PFDirectionInOut PFDirection = 0 21 | PFDirectionIn PFDirection = 1 22 | PFDirectionOut PFDirection = 2 23 | ) 24 | 25 | // PFLog provides the layer for 'pf' packet-filter logging, as described at 26 | // http://www.freebsd.org/cgi/man.cgi?query=pflog&sektion=4 27 | type PFLog struct { 28 | BaseLayer 29 | Length uint8 30 | Family ProtocolFamily 31 | Action, Reason uint8 32 | IFName, Ruleset []byte 33 | RuleNum, SubruleNum uint32 34 | UID uint32 35 | PID int32 36 | RuleUID uint32 37 | RulePID int32 38 | Direction PFDirection 39 | // The remainder is padding 40 | } 41 | 42 | func (pf *PFLog) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error { 43 | if len(data) < 60 { 44 | df.SetTruncated() 45 | return errors.New("PFLog data less than 60 bytes") 46 | } 47 | pf.Length = data[0] 48 | pf.Family = ProtocolFamily(data[1]) 49 | pf.Action = data[2] 50 | pf.Reason = data[3] 51 | pf.IFName = data[4:20] 52 | pf.Ruleset = data[20:36] 53 | pf.RuleNum = binary.BigEndian.Uint32(data[36:40]) 54 | pf.SubruleNum = binary.BigEndian.Uint32(data[40:44]) 55 | pf.UID = binary.BigEndian.Uint32(data[44:48]) 56 | pf.PID = int32(binary.BigEndian.Uint32(data[48:52])) 57 | pf.RuleUID = binary.BigEndian.Uint32(data[52:56]) 58 | pf.RulePID = int32(binary.BigEndian.Uint32(data[56:60])) 59 | pf.Direction = PFDirection(data[60]) 60 | if pf.Length%4 != 1 { 61 | return errors.New("PFLog header length should be 3 less than multiple of 4") 62 | } 63 | actualLength := int(pf.Length) + 3 64 | if len(data) < actualLength { 65 | return fmt.Errorf("PFLog data size < %d", actualLength) 66 | } 67 | pf.Contents = data[:actualLength] 68 | pf.Payload = data[actualLength:] 69 | return nil 70 | } 71 | 72 | // LayerType returns layers.LayerTypePFLog 73 | func (pf *PFLog) LayerType() gopacket.LayerType { return LayerTypePFLog } 74 | 75 | func (pf *PFLog) CanDecode() gopacket.LayerClass { return LayerTypePFLog } 76 | 77 | func (pf *PFLog) NextLayerType() gopacket.LayerType { 78 | return pf.Family.LayerType() 79 | } 80 | 81 | func decodePFLog(data []byte, p gopacket.PacketBuilder) error { 82 | pf := &PFLog{} 83 | return decodingLayerDecoder(pf, data, p) 84 | } 85 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/layers/ppp.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google, Inc. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. 6 | 7 | package layers 8 | 9 | import ( 10 | "encoding/binary" 11 | "errors" 12 | "github.com/google/gopacket" 13 | ) 14 | 15 | // PPP is the layer for PPP encapsulation headers. 16 | type PPP struct { 17 | BaseLayer 18 | PPPType PPPType 19 | HasPPTPHeader bool 20 | } 21 | 22 | // PPPEndpoint is a singleton endpoint for PPP. Since there is no actual 23 | // addressing for the two ends of a PPP connection, we use a singleton value 24 | // named 'point' for each endpoint. 25 | var PPPEndpoint = gopacket.NewEndpoint(EndpointPPP, nil) 26 | 27 | // PPPFlow is a singleton flow for PPP. Since there is no actual addressing for 28 | // the two ends of a PPP connection, we use a singleton value to represent the 29 | // flow for all PPP connections. 30 | var PPPFlow = gopacket.NewFlow(EndpointPPP, nil, nil) 31 | 32 | // LayerType returns LayerTypePPP 33 | func (p *PPP) LayerType() gopacket.LayerType { return LayerTypePPP } 34 | 35 | // LinkFlow returns PPPFlow. 36 | func (p *PPP) LinkFlow() gopacket.Flow { return PPPFlow } 37 | 38 | func decodePPP(data []byte, p gopacket.PacketBuilder) error { 39 | ppp := &PPP{} 40 | offset := 0 41 | if data[0] == 0xff && data[1] == 0x03 { 42 | offset = 2 43 | ppp.HasPPTPHeader = true 44 | } 45 | if data[offset]&0x1 == 0 { 46 | if data[offset+1]&0x1 == 0 { 47 | return errors.New("PPP has invalid type") 48 | } 49 | ppp.PPPType = PPPType(binary.BigEndian.Uint16(data[offset : offset+2])) 50 | ppp.Contents = data[offset : offset+2] 51 | ppp.Payload = data[offset+2:] 52 | } else { 53 | ppp.PPPType = PPPType(data[offset]) 54 | ppp.Contents = data[offset : offset+1] 55 | ppp.Payload = data[offset+1:] 56 | } 57 | p.AddLayer(ppp) 58 | p.SetLinkLayer(ppp) 59 | return p.NextDecoder(ppp.PPPType) 60 | } 61 | 62 | // SerializeTo writes the serialized form of this layer into the 63 | // SerializationBuffer, implementing gopacket.SerializableLayer. 64 | // See the docs for gopacket.SerializableLayer for more info. 65 | func (p *PPP) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { 66 | if p.PPPType&0x100 == 0 { 67 | bytes, err := b.PrependBytes(2) 68 | if err != nil { 69 | return err 70 | } 71 | binary.BigEndian.PutUint16(bytes, uint16(p.PPPType)) 72 | } else { 73 | bytes, err := b.PrependBytes(1) 74 | if err != nil { 75 | return err 76 | } 77 | bytes[0] = uint8(p.PPPType) 78 | } 79 | if p.HasPPTPHeader { 80 | bytes, err := b.PrependBytes(2) 81 | if err != nil { 82 | return err 83 | } 84 | bytes[0] = 0xff 85 | bytes[1] = 0x03 86 | } 87 | return nil 88 | } 89 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/layers/pppoe.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google, Inc. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. 6 | 7 | package layers 8 | 9 | import ( 10 | "encoding/binary" 11 | "github.com/google/gopacket" 12 | ) 13 | 14 | // PPPoE is the layer for PPPoE encapsulation headers. 15 | type PPPoE struct { 16 | BaseLayer 17 | Version uint8 18 | Type uint8 19 | Code PPPoECode 20 | SessionId uint16 21 | Length uint16 22 | } 23 | 24 | // LayerType returns gopacket.LayerTypePPPoE. 25 | func (p *PPPoE) LayerType() gopacket.LayerType { 26 | return LayerTypePPPoE 27 | } 28 | 29 | // decodePPPoE decodes the PPPoE header (see http://tools.ietf.org/html/rfc2516). 30 | func decodePPPoE(data []byte, p gopacket.PacketBuilder) error { 31 | pppoe := &PPPoE{ 32 | Version: data[0] >> 4, 33 | Type: data[0] & 0x0F, 34 | Code: PPPoECode(data[1]), 35 | SessionId: binary.BigEndian.Uint16(data[2:4]), 36 | Length: binary.BigEndian.Uint16(data[4:6]), 37 | } 38 | pppoe.BaseLayer = BaseLayer{data[:6], data[6 : 6+pppoe.Length]} 39 | p.AddLayer(pppoe) 40 | return p.NextDecoder(pppoe.Code) 41 | } 42 | 43 | // SerializeTo writes the serialized form of this layer into the 44 | // SerializationBuffer, implementing gopacket.SerializableLayer. 45 | // See the docs for gopacket.SerializableLayer for more info. 46 | func (p *PPPoE) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error { 47 | payload := b.Bytes() 48 | bytes, err := b.PrependBytes(6) 49 | if err != nil { 50 | return err 51 | } 52 | bytes[0] = (p.Version << 4) | p.Type 53 | bytes[1] = byte(p.Code) 54 | binary.BigEndian.PutUint16(bytes[2:], p.SessionId) 55 | if opts.FixLengths { 56 | p.Length = uint16(len(payload)) 57 | } 58 | binary.BigEndian.PutUint16(bytes[4:], p.Length) 59 | return nil 60 | } 61 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/layers/stp.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 Google, Inc. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. 6 | 7 | package layers 8 | 9 | import ( 10 | "github.com/google/gopacket" 11 | ) 12 | 13 | // STP decode spanning tree protocol packets to transport BPDU (bridge protocol data unit) message. 14 | type STP struct { 15 | BaseLayer 16 | } 17 | 18 | // LayerType returns gopacket.LayerTypeSTP. 19 | func (s *STP) LayerType() gopacket.LayerType { return LayerTypeSTP } 20 | 21 | func decodeSTP(data []byte, p gopacket.PacketBuilder) error { 22 | stp := &STP{} 23 | stp.Contents = data[:] 24 | // TODO: parse the STP protocol into actual subfields. 25 | p.AddLayer(stp) 26 | return nil 27 | } 28 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/layers/tls_appdata.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The GoPacket Authors. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. 6 | 7 | package layers 8 | 9 | import ( 10 | "errors" 11 | 12 | "github.com/google/gopacket" 13 | ) 14 | 15 | // TLSAppDataRecord contains all the information that each AppData Record types should have 16 | type TLSAppDataRecord struct { 17 | TLSRecordHeader 18 | Payload []byte 19 | } 20 | 21 | // DecodeFromBytes decodes the slice into the TLS struct. 22 | func (t *TLSAppDataRecord) decodeFromBytes(h TLSRecordHeader, data []byte, df gopacket.DecodeFeedback) error { 23 | // TLS Record Header 24 | t.ContentType = h.ContentType 25 | t.Version = h.Version 26 | t.Length = h.Length 27 | 28 | if len(data) != int(t.Length) { 29 | return errors.New("TLS Application Data length mismatch") 30 | } 31 | 32 | t.Payload = data 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/layers/tls_cipherspec.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The GoPacket Authors. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. 6 | 7 | package layers 8 | 9 | import ( 10 | "errors" 11 | 12 | "github.com/google/gopacket" 13 | ) 14 | 15 | // TLSchangeCipherSpec defines the message value inside ChangeCipherSpec Record 16 | type TLSchangeCipherSpec uint8 17 | 18 | const ( 19 | TLSChangecipherspecMessage TLSchangeCipherSpec = 1 20 | TLSChangecipherspecUnknown TLSchangeCipherSpec = 255 21 | ) 22 | 23 | // TLS Change Cipher Spec 24 | // 0 1 2 3 4 5 6 7 8 25 | // +--+--+--+--+--+--+--+--+ 26 | // | Message | 27 | // +--+--+--+--+--+--+--+--+ 28 | 29 | // TLSChangeCipherSpecRecord defines the type of data inside ChangeCipherSpec Record 30 | type TLSChangeCipherSpecRecord struct { 31 | TLSRecordHeader 32 | 33 | Message TLSchangeCipherSpec 34 | } 35 | 36 | // DecodeFromBytes decodes the slice into the TLS struct. 37 | func (t *TLSChangeCipherSpecRecord) decodeFromBytes(h TLSRecordHeader, data []byte, df gopacket.DecodeFeedback) error { 38 | // TLS Record Header 39 | t.ContentType = h.ContentType 40 | t.Version = h.Version 41 | t.Length = h.Length 42 | 43 | if len(data) != 1 { 44 | df.SetTruncated() 45 | return errors.New("TLS Change Cipher Spec record incorrect length") 46 | } 47 | 48 | t.Message = TLSchangeCipherSpec(data[0]) 49 | if t.Message != TLSChangecipherspecMessage { 50 | t.Message = TLSChangecipherspecUnknown 51 | } 52 | 53 | return nil 54 | } 55 | 56 | // String shows the message value nicely formatted 57 | func (ccs TLSchangeCipherSpec) String() string { 58 | switch ccs { 59 | default: 60 | return "Unknown" 61 | case TLSChangecipherspecMessage: 62 | return "Change Cipher Spec Message" 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/layers/tls_handshake.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The GoPacket Authors. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. 6 | 7 | package layers 8 | 9 | import ( 10 | "github.com/google/gopacket" 11 | ) 12 | 13 | // TLSHandshakeRecord defines the structure of a Handshare Record 14 | type TLSHandshakeRecord struct { 15 | TLSRecordHeader 16 | } 17 | 18 | // DecodeFromBytes decodes the slice into the TLS struct. 19 | func (t *TLSHandshakeRecord) decodeFromBytes(h TLSRecordHeader, data []byte, df gopacket.DecodeFeedback) error { 20 | // TLS Record Header 21 | t.ContentType = h.ContentType 22 | t.Version = h.Version 23 | t.Length = h.Length 24 | 25 | // TODO 26 | 27 | return nil 28 | } 29 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/layers/udplite.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Google, Inc. All rights reserved. 2 | // Copyright 2009-2011 Andreas Krennmair. All rights reserved. 3 | // 4 | // Use of this source code is governed by a BSD-style license 5 | // that can be found in the LICENSE file in the root of the source 6 | // tree. 7 | 8 | package layers 9 | 10 | import ( 11 | "encoding/binary" 12 | "github.com/google/gopacket" 13 | ) 14 | 15 | // UDPLite is the layer for UDP-Lite headers (rfc 3828). 16 | type UDPLite struct { 17 | BaseLayer 18 | SrcPort, DstPort UDPLitePort 19 | ChecksumCoverage uint16 20 | Checksum uint16 21 | sPort, dPort []byte 22 | } 23 | 24 | // LayerType returns gopacket.LayerTypeUDPLite 25 | func (u *UDPLite) LayerType() gopacket.LayerType { return LayerTypeUDPLite } 26 | 27 | func decodeUDPLite(data []byte, p gopacket.PacketBuilder) error { 28 | udp := &UDPLite{ 29 | SrcPort: UDPLitePort(binary.BigEndian.Uint16(data[0:2])), 30 | sPort: data[0:2], 31 | DstPort: UDPLitePort(binary.BigEndian.Uint16(data[2:4])), 32 | dPort: data[2:4], 33 | ChecksumCoverage: binary.BigEndian.Uint16(data[4:6]), 34 | Checksum: binary.BigEndian.Uint16(data[6:8]), 35 | BaseLayer: BaseLayer{data[:8], data[8:]}, 36 | } 37 | p.AddLayer(udp) 38 | p.SetTransportLayer(udp) 39 | return p.NextDecoder(gopacket.LayerTypePayload) 40 | } 41 | 42 | func (u *UDPLite) TransportFlow() gopacket.Flow { 43 | return gopacket.NewFlow(EndpointUDPLitePort, u.sPort, u.dPort) 44 | } 45 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/pcap/defs_windows_386.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The GoPacket Authors. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. 6 | 7 | // This file contains necessary structs/constants generated from libpcap headers with cgo -godefs 8 | // generated with: generate_defs.exe 9 | // DO NOT MODIFY 10 | 11 | package pcap 12 | 13 | import "syscall" 14 | 15 | const errorBufferSize = 0x100 16 | 17 | const ( 18 | pcapErrorNotActivated = -0x3 19 | pcapErrorActivated = -0x4 20 | pcapWarningPromisc = 0x2 21 | pcapErrorNoSuchDevice = -0x5 22 | pcapErrorDenied = -0x8 23 | pcapErrorNotUp = -0x9 24 | pcapError = -0x1 25 | pcapWarning = 0x1 26 | pcapDIN = 0x1 27 | pcapDOUT = 0x2 28 | pcapDINOUT = 0x0 29 | pcapNetmaskUnknown = 0xffffffff 30 | pcapTstampPrecisionMicro = 0x0 31 | pcapTstampPrecisionNano = 0x1 32 | ) 33 | 34 | type timeval struct { 35 | Sec int32 36 | Usec int32 37 | } 38 | type pcapPkthdr struct { 39 | Ts timeval 40 | Caplen uint32 41 | Len uint32 42 | } 43 | type pcapTPtr uintptr 44 | type pcapBpfInstruction struct { 45 | Code uint16 46 | Jt uint8 47 | Jf uint8 48 | K uint32 49 | } 50 | type pcapBpfProgram struct { 51 | Len uint32 52 | Insns *pcapBpfInstruction 53 | } 54 | type pcapStats struct { 55 | Recv uint32 56 | Drop uint32 57 | Ifdrop uint32 58 | } 59 | type pcapCint int32 60 | type pcapIf struct { 61 | Next *pcapIf 62 | Name *int8 63 | Description *int8 64 | Addresses *pcapAddr 65 | Flags uint32 66 | } 67 | 68 | type pcapAddr struct { 69 | Next *pcapAddr 70 | Addr *syscall.RawSockaddr 71 | Netmask *syscall.RawSockaddr 72 | Broadaddr *syscall.RawSockaddr 73 | Dstaddr *syscall.RawSockaddr 74 | } 75 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/pcap/defs_windows_amd64.go: -------------------------------------------------------------------------------- 1 | // Copyright 2019 The GoPacket Authors. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. 6 | 7 | // This file contains necessary structs/constants generated from libpcap headers with cgo -godefs 8 | // generated with: generate_defs.exe 9 | // DO NOT MODIFY 10 | 11 | package pcap 12 | 13 | import "syscall" 14 | 15 | const errorBufferSize = 0x100 16 | 17 | const ( 18 | pcapErrorNotActivated = -0x3 19 | pcapErrorActivated = -0x4 20 | pcapWarningPromisc = 0x2 21 | pcapErrorNoSuchDevice = -0x5 22 | pcapErrorDenied = -0x8 23 | pcapErrorNotUp = -0x9 24 | pcapError = -0x1 25 | pcapWarning = 0x1 26 | pcapDIN = 0x1 27 | pcapDOUT = 0x2 28 | pcapDINOUT = 0x0 29 | pcapNetmaskUnknown = 0xffffffff 30 | pcapTstampPrecisionMicro = 0x0 31 | pcapTstampPrecisionNano = 0x1 32 | ) 33 | 34 | type timeval struct { 35 | Sec int32 36 | Usec int32 37 | } 38 | type pcapPkthdr struct { 39 | Ts timeval 40 | Caplen uint32 41 | Len uint32 42 | } 43 | type pcapTPtr uintptr 44 | type pcapBpfInstruction struct { 45 | Code uint16 46 | Jt uint8 47 | Jf uint8 48 | K uint32 49 | } 50 | type pcapBpfProgram struct { 51 | Len uint32 52 | Pad_cgo_0 [4]byte 53 | Insns *pcapBpfInstruction 54 | } 55 | type pcapStats struct { 56 | Recv uint32 57 | Drop uint32 58 | Ifdrop uint32 59 | } 60 | type pcapCint int32 61 | type pcapIf struct { 62 | Next *pcapIf 63 | Name *int8 64 | Description *int8 65 | Addresses *pcapAddr 66 | Flags uint32 67 | Pad_cgo_0 [4]byte 68 | } 69 | 70 | type pcapAddr struct { 71 | Next *pcapAddr 72 | Addr *syscall.RawSockaddr 73 | Netmask *syscall.RawSockaddr 74 | Broadaddr *syscall.RawSockaddr 75 | Dstaddr *syscall.RawSockaddr 76 | } 77 | -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/pcap/test_dns.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flier/gohs/9dd8ff12354342d63a6e036780f4b19c7ac9ce01/vendor/github.com/google/gopacket/pcap/test_dns.pcap -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/pcap/test_ethernet.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flier/gohs/9dd8ff12354342d63a6e036780f4b19c7ac9ce01/vendor/github.com/google/gopacket/pcap/test_ethernet.pcap -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/pcap/test_loopback.pcap: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/flier/gohs/9dd8ff12354342d63a6e036780f4b19c7ac9ce01/vendor/github.com/google/gopacket/pcap/test_loopback.pcap -------------------------------------------------------------------------------- /vendor/github.com/google/gopacket/time.go: -------------------------------------------------------------------------------- 1 | // Copyright 2018 The GoPacket Authors. All rights reserved. 2 | // 3 | // Use of this source code is governed by a BSD-style license 4 | // that can be found in the LICENSE file in the root of the source 5 | // tree. 6 | 7 | package gopacket 8 | 9 | import ( 10 | "fmt" 11 | "math" 12 | "time" 13 | ) 14 | 15 | // TimestampResolution represents the resolution of timestamps in Base^Exponent. 16 | type TimestampResolution struct { 17 | Base, Exponent int 18 | } 19 | 20 | func (t TimestampResolution) String() string { 21 | return fmt.Sprintf("%d^%d", t.Base, t.Exponent) 22 | } 23 | 24 | // ToDuration returns the smallest representable time difference as a time.Duration 25 | func (t TimestampResolution) ToDuration() time.Duration { 26 | if t.Base == 0 { 27 | return 0 28 | } 29 | if t.Exponent == 0 { 30 | return time.Second 31 | } 32 | switch t.Base { 33 | case 10: 34 | return time.Duration(math.Pow10(t.Exponent + 9)) 35 | case 2: 36 | if t.Exponent < 0 { 37 | return time.Second >> uint(-t.Exponent) 38 | } 39 | return time.Second << uint(t.Exponent) 40 | default: 41 | // this might loose precision 42 | return time.Duration(float64(time.Second) * math.Pow(float64(t.Base), float64(t.Exponent))) 43 | } 44 | } 45 | 46 | // TimestampResolutionInvalid represents an invalid timestamp resolution 47 | var TimestampResolutionInvalid = TimestampResolution{} 48 | 49 | // TimestampResolutionMillisecond is a resolution of 10^-3s 50 | var TimestampResolutionMillisecond = TimestampResolution{10, -3} 51 | 52 | // TimestampResolutionMicrosecond is a resolution of 10^-6s 53 | var TimestampResolutionMicrosecond = TimestampResolution{10, -6} 54 | 55 | // TimestampResolutionNanosecond is a resolution of 10^-9s 56 | var TimestampResolutionNanosecond = TimestampResolution{10, -9} 57 | 58 | // TimestampResolutionNTP is the resolution of NTP timestamps which is 2^-32 ≈ 233 picoseconds 59 | var TimestampResolutionNTP = TimestampResolution{2, -32} 60 | 61 | // TimestampResolutionCaptureInfo is the resolution used in CaptureInfo, which his currently nanosecond 62 | var TimestampResolutionCaptureInfo = TimestampResolutionNanosecond 63 | 64 | // PacketSourceResolution is an interface for packet data sources that 65 | // support reporting the timestamp resolution of the aqcuired timestamps. 66 | // Returned timestamps will always have NanosecondTimestampResolution due 67 | // to the use of time.Time, but scaling might have occured if acquired 68 | // timestamps have a different resolution. 69 | type PacketSourceResolution interface { 70 | // Resolution returns the timestamp resolution of acquired timestamps before scaling to NanosecondTimestampResolution. 71 | Resolution() TimestampResolution 72 | } 73 | -------------------------------------------------------------------------------- /vendor/github.com/gopherjs/gopherjs/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013 Richard Musiol. 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 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 15 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 16 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 17 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 18 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 19 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 20 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /vendor/github.com/jtolds/gls/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Space Monkey, Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /vendor/github.com/jtolds/gls/gen_sym.go: -------------------------------------------------------------------------------- 1 | package gls 2 | 3 | import ( 4 | "sync" 5 | ) 6 | 7 | var ( 8 | keyMtx sync.Mutex 9 | keyCounter uint64 10 | ) 11 | 12 | // ContextKey is a throwaway value you can use as a key to a ContextManager 13 | type ContextKey struct{ id uint64 } 14 | 15 | // GenSym will return a brand new, never-before-used ContextKey 16 | func GenSym() ContextKey { 17 | keyMtx.Lock() 18 | defer keyMtx.Unlock() 19 | keyCounter += 1 20 | return ContextKey{id: keyCounter} 21 | } 22 | -------------------------------------------------------------------------------- /vendor/github.com/jtolds/gls/gid.go: -------------------------------------------------------------------------------- 1 | package gls 2 | 3 | var ( 4 | stackTagPool = &idPool{} 5 | ) 6 | 7 | // Will return this goroutine's identifier if set. If you always need a 8 | // goroutine identifier, you should use EnsureGoroutineId which will make one 9 | // if there isn't one already. 10 | func GetGoroutineId() (gid uint, ok bool) { 11 | return readStackTag() 12 | } 13 | 14 | // Will call cb with the current goroutine identifier. If one hasn't already 15 | // been generated, one will be created and set first. The goroutine identifier 16 | // might be invalid after cb returns. 17 | func EnsureGoroutineId(cb func(gid uint)) { 18 | if gid, ok := readStackTag(); ok { 19 | cb(gid) 20 | return 21 | } 22 | gid := stackTagPool.Acquire() 23 | defer stackTagPool.Release(gid) 24 | addStackTag(gid, func() { cb(gid) }) 25 | } 26 | -------------------------------------------------------------------------------- /vendor/github.com/jtolds/gls/id_pool.go: -------------------------------------------------------------------------------- 1 | package gls 2 | 3 | // though this could probably be better at keeping ids smaller, the goal of 4 | // this class is to keep a registry of the smallest unique integer ids 5 | // per-process possible 6 | 7 | import ( 8 | "sync" 9 | ) 10 | 11 | type idPool struct { 12 | mtx sync.Mutex 13 | released []uint 14 | max_id uint 15 | } 16 | 17 | func (p *idPool) Acquire() (id uint) { 18 | p.mtx.Lock() 19 | defer p.mtx.Unlock() 20 | if len(p.released) > 0 { 21 | id = p.released[len(p.released)-1] 22 | p.released = p.released[:len(p.released)-1] 23 | return id 24 | } 25 | id = p.max_id 26 | p.max_id++ 27 | return id 28 | } 29 | 30 | func (p *idPool) Release(id uint) { 31 | p.mtx.Lock() 32 | defer p.mtx.Unlock() 33 | p.released = append(p.released, id) 34 | } 35 | -------------------------------------------------------------------------------- /vendor/github.com/jtolds/gls/stack_tags_js.go: -------------------------------------------------------------------------------- 1 | // +build js 2 | 3 | package gls 4 | 5 | // This file is used for GopherJS builds, which don't have normal runtime 6 | // stack trace support 7 | 8 | import ( 9 | "strconv" 10 | "strings" 11 | 12 | "github.com/gopherjs/gopherjs/js" 13 | ) 14 | 15 | const ( 16 | jsFuncNamePrefix = "github_com_jtolds_gls_mark" 17 | ) 18 | 19 | func jsMarkStack() (f []uintptr) { 20 | lines := strings.Split( 21 | js.Global.Get("Error").New().Get("stack").String(), "\n") 22 | f = make([]uintptr, 0, len(lines)) 23 | for i, line := range lines { 24 | line = strings.TrimSpace(line) 25 | if line == "" { 26 | continue 27 | } 28 | if i == 0 { 29 | if line != "Error" { 30 | panic("didn't understand js stack trace") 31 | } 32 | continue 33 | } 34 | fields := strings.Fields(line) 35 | if len(fields) < 2 || fields[0] != "at" { 36 | panic("didn't understand js stack trace") 37 | } 38 | 39 | pos := strings.Index(fields[1], jsFuncNamePrefix) 40 | if pos < 0 { 41 | continue 42 | } 43 | pos += len(jsFuncNamePrefix) 44 | if pos >= len(fields[1]) { 45 | panic("didn't understand js stack trace") 46 | } 47 | char := string(fields[1][pos]) 48 | switch char { 49 | case "S": 50 | f = append(f, uintptr(0)) 51 | default: 52 | val, err := strconv.ParseUint(char, 16, 8) 53 | if err != nil { 54 | panic("didn't understand js stack trace") 55 | } 56 | f = append(f, uintptr(val)+1) 57 | } 58 | } 59 | return f 60 | } 61 | 62 | // variables to prevent inlining 63 | var ( 64 | findPtr = func() uintptr { 65 | funcs := jsMarkStack() 66 | if len(funcs) == 0 { 67 | panic("failed to find function pointer") 68 | } 69 | return funcs[0] 70 | } 71 | 72 | getStack = func(offset, amount int) (stack []uintptr, next_offset int) { 73 | return jsMarkStack(), 0 74 | } 75 | ) 76 | -------------------------------------------------------------------------------- /vendor/github.com/jtolds/gls/stack_tags_main.go: -------------------------------------------------------------------------------- 1 | // +build !js 2 | 3 | package gls 4 | 5 | // This file is used for standard Go builds, which have the expected runtime 6 | // support 7 | 8 | import ( 9 | "runtime" 10 | ) 11 | 12 | var ( 13 | findPtr = func() uintptr { 14 | var pc [1]uintptr 15 | n := runtime.Callers(4, pc[:]) 16 | if n != 1 { 17 | panic("failed to find function pointer") 18 | } 19 | return pc[0] 20 | } 21 | 22 | getStack = func(offset, amount int) (stack []uintptr, next_offset int) { 23 | stack = make([]uintptr, amount) 24 | stack = stack[:runtime.Callers(offset, stack)] 25 | if len(stack) < amount { 26 | return stack, 0 27 | } 28 | return stack, offset + len(stack) 29 | } 30 | ) 31 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /coverage.* 3 | .DS_Store 4 | *.iml 5 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/.travis.yml: -------------------------------------------------------------------------------- 1 | dist: bionic 2 | 3 | language: go 4 | 5 | go: 6 | - 1.x 7 | 8 | env: 9 | - GO111MODULE=on 10 | 11 | script: 12 | - make build 13 | 14 | after_success: 15 | - bash <(curl -s https://codecov.io/bash) 16 | 17 | git: 18 | depth: 1 19 | 20 | cache: 21 | directories: 22 | - $HOME/.cache/go-build 23 | - $HOME/gopath/pkg/mod 24 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | In general, the code posted to the [Smarty github organization](https://github.com/smarty) is created to solve specific problems at Smarty that are ancillary to our core products in the address verification industry and may or may not be useful to other organizations or developers. Our reason for posting said code isn't necessarily to solicit feedback or contributions from the community but more as a showcase of some of the approaches to solving problems we have adopted. 4 | 5 | Having stated that, we do consider issues raised by other githubbers as well as contributions submitted via pull requests. When submitting such a pull request, please follow these guidelines: 6 | 7 | - _Look before you leap:_ If the changes you plan to make are significant, it's in everyone's best interest for you to discuss them with a Smarty team member prior to opening a pull request. 8 | - _License and ownership:_ If modifying the `LICENSE.md` file, limit your changes to fixing typographical mistakes. Do NOT modify the actual terms in the license or the copyright by **Smarty, LLC**. Code submitted to Smarty projects becomes property of Smarty and must be compatible with the associated license. 9 | - _Testing:_ If the code you are submitting resides in packages/modules covered by automated tests, be sure to add passing tests that cover your changes and assert expected behavior and state. Submit the additional test cases as part of your change set. 10 | - _Style:_ Match your approach to **naming** and **formatting** with the surrounding code. Basically, the code you submit shouldn't stand out. 11 | - "Naming" refers to such constructs as variables, methods, functions, classes, structs, interfaces, packages, modules, directories, files, etc... 12 | - "Formatting" refers to such constructs as whitespace, horizontal line length, vertical function length, vertical file length, indentation, curly braces, etc... 13 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 Smarty 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | NOTE: Various optional and subordinate components carry their own licensing 24 | requirements and restrictions. Use of those components is subject to the terms 25 | and conditions outlined the respective license of each component. 26 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/Makefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | test: fmt 4 | go test -timeout=1s -race -cover -short -count=1 ./... 5 | 6 | fmt: 7 | go fmt ./... 8 | 9 | compile: 10 | go build ./... 11 | 12 | build: test compile 13 | 14 | .PHONY: test compile build 15 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/README.md: -------------------------------------------------------------------------------- 1 | #### SMARTY DISCLAIMER: Subject to the terms of the associated license agreement, this software is freely available for your use. This software is FREE, AS IN PUPPIES, and is a gift. Enjoy your new responsibility. This means that while we may consider enhancement requests, we may or may not choose to entertain requests at our sole and absolute discretion. 2 | 3 | [![Build Status](https://travis-ci.org/smarty/assertions.svg?branch=master)](https://travis-ci.org/smarty/assertions) 4 | [![Code Coverage](https://codecov.io/gh/smarty/assertions/branch/master/graph/badge.svg)](https://codecov.io/gh/smarty/assertions) 5 | [![Go Report Card](https://goreportcard.com/badge/github.com/smarty/assertions)](https://goreportcard.com/report/github.com/smarty/assertions) 6 | [![GoDoc](https://godoc.org/github.com/smarty/assertions?status.svg)](http://godoc.org/github.com/smarty/assertions) 7 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/equal_method.go: -------------------------------------------------------------------------------- 1 | package assertions 2 | 3 | import "reflect" 4 | 5 | type equalityMethodSpecification struct{} 6 | 7 | func (this equalityMethodSpecification) assertable(a, b any) bool { 8 | if !bothAreSameType(a, b) { 9 | return false 10 | } 11 | if !typeHasEqualMethod(a) { 12 | return false 13 | } 14 | if !equalMethodReceivesSameTypeForComparison(a) { 15 | return false 16 | } 17 | if !equalMethodReturnsBool(a) { 18 | return false 19 | } 20 | return true 21 | } 22 | func bothAreSameType(a, b any) bool { 23 | aType := reflect.TypeOf(a) 24 | if aType == nil { 25 | return false 26 | } 27 | if aType.Kind() == reflect.Ptr { 28 | aType = aType.Elem() 29 | } 30 | bType := reflect.TypeOf(b) 31 | return aType == bType 32 | } 33 | func typeHasEqualMethod(a any) bool { 34 | aInstance := reflect.ValueOf(a) 35 | equalMethod := aInstance.MethodByName("Equal") 36 | return equalMethod != reflect.Value{} 37 | } 38 | func equalMethodReceivesSameTypeForComparison(a any) bool { 39 | aType := reflect.TypeOf(a) 40 | if aType.Kind() == reflect.Ptr { 41 | aType = aType.Elem() 42 | } 43 | aInstance := reflect.ValueOf(a) 44 | equalMethod := aInstance.MethodByName("Equal") 45 | signature := equalMethod.Type() 46 | return signature.NumIn() == 1 && signature.In(0) == aType 47 | } 48 | func equalMethodReturnsBool(a any) bool { 49 | aInstance := reflect.ValueOf(a) 50 | equalMethod := aInstance.MethodByName("Equal") 51 | signature := equalMethod.Type() 52 | return signature.NumOut() == 1 && signature.Out(0) == reflect.TypeOf(true) 53 | } 54 | 55 | func (this equalityMethodSpecification) passes(A, B any) bool { 56 | a := reflect.ValueOf(A) 57 | b := reflect.ValueOf(B) 58 | return areEqual(a, b) && areEqual(b, a) 59 | } 60 | func areEqual(receiver reflect.Value, argument reflect.Value) bool { 61 | equalMethod := receiver.MethodByName("Equal") 62 | argumentList := []reflect.Value{argument} 63 | result := equalMethod.Call(argumentList) 64 | return result[0].Bool() 65 | } 66 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/equality_diff.go: -------------------------------------------------------------------------------- 1 | package assertions 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/smarty/assertions/internal/go-diff/diffmatchpatch" 7 | ) 8 | 9 | func composePrettyDiff(expected, actual string) string { 10 | diff := diffmatchpatch.New() 11 | diffs := diff.DiffMain(expected, actual, false) 12 | if prettyDiffIsLikelyToBeHelpful(diffs) { 13 | return fmt.Sprintf("\nDiff: '%s'", diff.DiffPrettyText(diffs)) 14 | } 15 | return "" 16 | } 17 | 18 | // prettyDiffIsLikelyToBeHelpful returns true if the diff listing contains 19 | // more 'equal' segments than 'deleted'/'inserted' segments. 20 | func prettyDiffIsLikelyToBeHelpful(diffs []diffmatchpatch.Diff) bool { 21 | equal, deleted, inserted := measureDiffTypeLengths(diffs) 22 | return equal > deleted && equal > inserted 23 | } 24 | 25 | func measureDiffTypeLengths(diffs []diffmatchpatch.Diff) (equal, deleted, inserted int) { 26 | for _, segment := range diffs { 27 | switch segment.Type { 28 | case diffmatchpatch.DiffEqual: 29 | equal += len(segment.Text) 30 | case diffmatchpatch.DiffDelete: 31 | deleted += len(segment.Text) 32 | case diffmatchpatch.DiffInsert: 33 | inserted += len(segment.Text) 34 | } 35 | } 36 | return equal, deleted, inserted 37 | } 38 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/filter.go: -------------------------------------------------------------------------------- 1 | package assertions 2 | 3 | import "fmt" 4 | 5 | const ( 6 | success = "" 7 | needExactValues = "This assertion requires exactly %d comparison values (you provided %d)." 8 | needNonEmptyCollection = "This assertion requires at least 1 comparison value (you provided 0)." 9 | needFewerValues = "This assertion allows %d or fewer comparison values (you provided %d)." 10 | ) 11 | 12 | func need(needed int, expected []any) string { 13 | if len(expected) != needed { 14 | return fmt.Sprintf(needExactValues, needed, len(expected)) 15 | } 16 | return success 17 | } 18 | 19 | func atLeast(minimum int, expected []any) string { 20 | if len(expected) < minimum { 21 | return needNonEmptyCollection 22 | } 23 | return success 24 | } 25 | 26 | func atMost(max int, expected []any) string { 27 | if len(expected) > max { 28 | return fmt.Sprintf(needFewerValues, max, len(expected)) 29 | } 30 | return success 31 | } 32 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/internal/go-diff/AUTHORS: -------------------------------------------------------------------------------- 1 | # This is the official list of go-diff authors for copyright purposes. 2 | # This file is distinct from the CONTRIBUTORS files. 3 | # See the latter for an explanation. 4 | 5 | # Names should be added to this file as 6 | # Name or Organization 7 | # The email address is not required for organizations. 8 | 9 | # Please keep the list sorted. 10 | 11 | Danny Yoo 12 | James Kolb 13 | Jonathan Amsterdam 14 | Markus Zimmermann 15 | Matt Kovars 16 | Örjan Persson 17 | Osman Masood 18 | Robert Carlsen 19 | Rory Flynn 20 | Sergi Mansilla 21 | Shatrugna Sadhu 22 | Shawn Smith 23 | Stas Maksimov 24 | Tor Arvid Lund 25 | Zac Bergquist 26 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/internal/go-diff/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This is the official list of people who can contribute 2 | # (and typically have contributed) code to the go-diff 3 | # repository. 4 | # 5 | # The AUTHORS file lists the copyright holders; this file 6 | # lists people. For example, ACME Inc. employees would be listed here 7 | # but not in AUTHORS, because ACME Inc. would hold the copyright. 8 | # 9 | # When adding J Random Contributor's name to this file, 10 | # either J's name or J's organization's name should be 11 | # added to the AUTHORS file. 12 | # 13 | # Names should be added to this file like so: 14 | # Name 15 | # 16 | # Please keep the list sorted. 17 | 18 | Danny Yoo 19 | James Kolb 20 | Jonathan Amsterdam 21 | Markus Zimmermann 22 | Matt Kovars 23 | Örjan Persson 24 | Osman Masood 25 | Robert Carlsen 26 | Rory Flynn 27 | Sergi Mansilla 28 | Shatrugna Sadhu 29 | Shawn Smith 30 | Stas Maksimov 31 | Tor Arvid Lund 32 | Zac Bergquist 33 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/internal/go-diff/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2016 The go-diff Authors. All rights reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a 4 | copy of this software and associated documentation files (the "Software"), 5 | to deal in the Software without restriction, including without limitation 6 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | and/or sell copies of the Software, and to permit persons to whom the 8 | Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included 11 | in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 14 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | DEALINGS IN THE SOFTWARE. 20 | 21 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/internal/go-diff/diffmatchpatch/diffmatchpatch.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2016 The go-diff authors. All rights reserved. 2 | // https://github.com/sergi/go-diff 3 | // See the included LICENSE file for license details. 4 | // 5 | // go-diff is a Go implementation of Google's Diff, Match, and Patch library 6 | // Original library is Copyright (c) 2006 Google Inc. 7 | // http://code.google.com/p/google-diff-match-patch/ 8 | 9 | // Package diffmatchpatch offers robust algorithms to perform the operations required for synchronizing plain text. 10 | package diffmatchpatch 11 | 12 | import ( 13 | "time" 14 | ) 15 | 16 | // DiffMatchPatch holds the configuration for diff-match-patch operations. 17 | type DiffMatchPatch struct { 18 | // Number of seconds to map a diff before giving up (0 for infinity). 19 | DiffTimeout time.Duration 20 | // Cost of an empty edit operation in terms of edit characters. 21 | DiffEditCost int 22 | // How far to search for a match (0 = exact location, 1000+ = broad match). A match this many characters away from the expected location will add 1.0 to the score (0.0 is a perfect match). 23 | MatchDistance int 24 | // When deleting a large block of text (over ~64 characters), how close do the contents have to be to match the expected contents. (0.0 = perfection, 1.0 = very loose). Note that MatchThreshold controls how closely the end points of a delete need to match. 25 | PatchDeleteThreshold float64 26 | // Chunk size for context length. 27 | PatchMargin int 28 | // The number of bits in an int. 29 | MatchMaxBits int 30 | // At what point is no match declared (0.0 = perfection, 1.0 = very loose). 31 | MatchThreshold float64 32 | } 33 | 34 | // New creates a new DiffMatchPatch object with default parameters. 35 | func New() *DiffMatchPatch { 36 | // Defaults. 37 | return &DiffMatchPatch{ 38 | DiffTimeout: time.Second, 39 | DiffEditCost: 4, 40 | MatchThreshold: 0.5, 41 | MatchDistance: 1000, 42 | PatchDeleteThreshold: 0.5, 43 | PatchMargin: 4, 44 | MatchMaxBits: 32, 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/internal/go-diff/diffmatchpatch/mathutil.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2016 The go-diff authors. All rights reserved. 2 | // https://github.com/sergi/go-diff 3 | // See the included LICENSE file for license details. 4 | // 5 | // go-diff is a Go implementation of Google's Diff, Match, and Patch library 6 | // Original library is Copyright (c) 2006 Google Inc. 7 | // http://code.google.com/p/google-diff-match-patch/ 8 | 9 | package diffmatchpatch 10 | 11 | func min(x, y int) int { 12 | if x < y { 13 | return x 14 | } 15 | return y 16 | } 17 | 18 | func max(x, y int) int { 19 | if x > y { 20 | return x 21 | } 22 | return y 23 | } 24 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/internal/go-diff/diffmatchpatch/operation_string.go: -------------------------------------------------------------------------------- 1 | // Code generated by "stringer -type=Operation -trimprefix=Diff"; DO NOT EDIT. 2 | 3 | package diffmatchpatch 4 | 5 | import "fmt" 6 | 7 | const _Operation_name = "DeleteEqualInsert" 8 | 9 | var _Operation_index = [...]uint8{0, 6, 11, 17} 10 | 11 | func (i Operation) String() string { 12 | i -= -1 13 | if i < 0 || i >= Operation(len(_Operation_index)-1) { 14 | return fmt.Sprintf("Operation(%d)", i+-1) 15 | } 16 | return _Operation_name[_Operation_index[i]:_Operation_index[i+1]] 17 | } 18 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/internal/go-diff/diffmatchpatch/stringutil.go: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012-2016 The go-diff authors. All rights reserved. 2 | // https://github.com/sergi/go-diff 3 | // See the included LICENSE file for license details. 4 | // 5 | // go-diff is a Go implementation of Google's Diff, Match, and Patch library 6 | // Original library is Copyright (c) 2006 Google Inc. 7 | // http://code.google.com/p/google-diff-match-patch/ 8 | 9 | package diffmatchpatch 10 | 11 | import ( 12 | "strings" 13 | "unicode/utf8" 14 | ) 15 | 16 | // unescaper unescapes selected chars for compatibility with JavaScript's encodeURI. 17 | // In speed critical applications this could be dropped since the receiving application will certainly decode these fine. Note that this function is case-sensitive. Thus "%3F" would not be unescaped. But this is ok because it is only called with the output of HttpUtility.UrlEncode which returns lowercase hex. Example: "%3f" -> "?", "%24" -> "$", etc. 18 | var unescaper = strings.NewReplacer( 19 | "%21", "!", "%7E", "~", "%27", "'", 20 | "%28", "(", "%29", ")", "%3B", ";", 21 | "%2F", "/", "%3F", "?", "%3A", ":", 22 | "%40", "@", "%26", "&", "%3D", "=", 23 | "%2B", "+", "%24", "$", "%2C", ",", "%23", "#", "%2A", "*") 24 | 25 | // indexOf returns the first index of pattern in str, starting at str[i]. 26 | func indexOf(str string, pattern string, i int) int { 27 | if i > len(str)-1 { 28 | return -1 29 | } 30 | if i <= 0 { 31 | return strings.Index(str, pattern) 32 | } 33 | ind := strings.Index(str[i:], pattern) 34 | if ind == -1 { 35 | return -1 36 | } 37 | return ind + i 38 | } 39 | 40 | // lastIndexOf returns the last index of pattern in str, starting at str[i]. 41 | func lastIndexOf(str string, pattern string, i int) int { 42 | if i < 0 { 43 | return -1 44 | } 45 | if i >= len(str) { 46 | return strings.LastIndex(str, pattern) 47 | } 48 | _, size := utf8.DecodeRuneInString(str[i:]) 49 | return strings.LastIndex(str[:i+size], pattern) 50 | } 51 | 52 | // runesIndexOf returns the index of pattern in target, starting at target[i]. 53 | func runesIndexOf(target, pattern []rune, i int) int { 54 | if i > len(target)-1 { 55 | return -1 56 | } 57 | if i <= 0 { 58 | return runesIndex(target, pattern) 59 | } 60 | ind := runesIndex(target[i:], pattern) 61 | if ind == -1 { 62 | return -1 63 | } 64 | return ind + i 65 | } 66 | 67 | func runesEqual(r1, r2 []rune) bool { 68 | if len(r1) != len(r2) { 69 | return false 70 | } 71 | for i, c := range r1 { 72 | if c != r2[i] { 73 | return false 74 | } 75 | } 76 | return true 77 | } 78 | 79 | // runesIndex is the equivalent of strings.Index for rune slices. 80 | func runesIndex(r1, r2 []rune) int { 81 | last := len(r1) - len(r2) 82 | for i := 0; i <= last; i++ { 83 | if runesEqual(r1[i:i+len(r2)], r2) { 84 | return i 85 | } 86 | } 87 | return -1 88 | } 89 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/internal/go-render/LICENSE: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2015 The Chromium 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/github.com/smarty/assertions/internal/go-render/render/render_time.go: -------------------------------------------------------------------------------- 1 | package render 2 | 3 | import ( 4 | "reflect" 5 | "time" 6 | ) 7 | 8 | func renderTime(value reflect.Value) (string, bool) { 9 | if instant, ok := convertTime(value); !ok { 10 | return "", false 11 | } else if instant.IsZero() { 12 | return "0", true 13 | } else { 14 | return instant.String(), true 15 | } 16 | } 17 | 18 | func convertTime(value reflect.Value) (t time.Time, ok bool) { 19 | if value.Type() == timeType { 20 | defer func() { recover() }() 21 | t, ok = value.Interface().(time.Time) 22 | } 23 | return 24 | } 25 | 26 | var timeType = reflect.TypeOf(time.Time{}) 27 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/internal/oglematchers/.gitignore: -------------------------------------------------------------------------------- 1 | *.6 2 | 6.out 3 | _obj/ 4 | _test/ 5 | _testmain.go 6 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/internal/oglematchers/.travis.yml: -------------------------------------------------------------------------------- 1 | # Cf. http://docs.travis-ci.com/user/getting-started/ 2 | # Cf. http://docs.travis-ci.com/user/languages/go/ 3 | 4 | language: go 5 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/internal/oglematchers/README.md: -------------------------------------------------------------------------------- 1 | [![GoDoc](https://godoc.org/github.com/smarty/assertions/internal/oglematchers?status.svg)](https://godoc.org/github.com/smarty/assertions/internal/oglematchers) 2 | 3 | `oglematchers` is a package for the Go programming language containing a set of 4 | matchers, useful in a testing or mocking framework, inspired by and mostly 5 | compatible with [Google Test][googletest] for C++ and 6 | [Google JS Test][google-js-test]. The package is used by the 7 | [ogletest][ogletest] testing framework and [oglemock][oglemock] mocking 8 | framework, which may be more directly useful to you, but can be generically used 9 | elsewhere as well. 10 | 11 | A "matcher" is simply an object with a `Matches` method defining a set of golang 12 | values matched by the matcher, and a `Description` method describing that set. 13 | For example, here are some matchers: 14 | 15 | ```go 16 | // Numbers 17 | Equals(17.13) 18 | LessThan(19) 19 | 20 | // Strings 21 | Equals("taco") 22 | HasSubstr("burrito") 23 | MatchesRegex("t.*o") 24 | 25 | // Combining matchers 26 | AnyOf(LessThan(17), GreaterThan(19)) 27 | ``` 28 | 29 | There are lots more; see [here][reference] for a reference. You can also add 30 | your own simply by implementing the `oglematchers.Matcher` interface. 31 | 32 | 33 | Installation 34 | ------------ 35 | 36 | First, make sure you have installed Go 1.0.2 or newer. See 37 | [here][golang-install] for instructions. 38 | 39 | Use the following command to install `oglematchers` and keep it up to date: 40 | 41 | go get -u github.com/smarty/assertions/internal/oglematchers 42 | 43 | 44 | Documentation 45 | ------------- 46 | 47 | See [here][reference] for documentation. Alternatively, you can install the 48 | package and then use `godoc`: 49 | 50 | godoc github.com/smarty/assertions/internal/oglematchers 51 | 52 | 53 | [reference]: http://godoc.org/github.com/smarty/assertions/internal/oglematchers 54 | [golang-install]: http://golang.org/doc/install.html 55 | [googletest]: http://code.google.com/p/googletest/ 56 | [google-js-test]: http://code.google.com/p/google-js-test/ 57 | [ogletest]: http://github.com/smarty/assertions/internal/ogletest 58 | [oglemock]: http://github.com/smarty/assertions/internal/oglemock 59 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/internal/oglematchers/any_of.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | import ( 19 | "errors" 20 | "fmt" 21 | "reflect" 22 | "strings" 23 | ) 24 | 25 | // AnyOf accepts a set of values S and returns a matcher that follows the 26 | // algorithm below when considering a candidate c: 27 | // 28 | // 1. If there exists a value m in S such that m implements the Matcher 29 | // interface and m matches c, return true. 30 | // 31 | // 2. Otherwise, if there exists a value v in S such that v does not implement 32 | // the Matcher interface and the matcher Equals(v) matches c, return true. 33 | // 34 | // 3. Otherwise, if there is a value m in S such that m implements the Matcher 35 | // interface and m returns a fatal error for c, return that fatal error. 36 | // 37 | // 4. Otherwise, return false. 38 | // 39 | // This is akin to a logical OR operation for matchers, with non-matchers x 40 | // being treated as Equals(x). 41 | func AnyOf(vals ...any) Matcher { 42 | // Get ahold of a type variable for the Matcher interface. 43 | var dummy *Matcher 44 | matcherType := reflect.TypeOf(dummy).Elem() 45 | 46 | // Create a matcher for each value, or use the value itself if it's already a 47 | // matcher. 48 | wrapped := make([]Matcher, len(vals)) 49 | for i, v := range vals { 50 | t := reflect.TypeOf(v) 51 | if t != nil && t.Implements(matcherType) { 52 | wrapped[i] = v.(Matcher) 53 | } else { 54 | wrapped[i] = Equals(v) 55 | } 56 | } 57 | 58 | return &anyOfMatcher{wrapped} 59 | } 60 | 61 | type anyOfMatcher struct { 62 | wrapped []Matcher 63 | } 64 | 65 | func (m *anyOfMatcher) Description() string { 66 | wrappedDescs := make([]string, len(m.wrapped)) 67 | for i, matcher := range m.wrapped { 68 | wrappedDescs[i] = matcher.Description() 69 | } 70 | 71 | return fmt.Sprintf("or(%s)", strings.Join(wrappedDescs, ", ")) 72 | } 73 | 74 | func (m *anyOfMatcher) Matches(c any) (err error) { 75 | err = errors.New("") 76 | 77 | // Try each matcher in turn. 78 | for _, matcher := range m.wrapped { 79 | wrappedErr := matcher.Matches(c) 80 | 81 | // Return immediately if there's a match. 82 | if wrappedErr == nil { 83 | err = nil 84 | return 85 | } 86 | 87 | // Note the fatal error, if any. 88 | if _, isFatal := wrappedErr.(*FatalError); isFatal { 89 | err = wrappedErr 90 | } 91 | } 92 | 93 | return 94 | } 95 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/internal/oglematchers/contains.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | import ( 19 | "fmt" 20 | "reflect" 21 | ) 22 | 23 | // Return a matcher that matches arrays slices with at least one element that 24 | // matches the supplied argument. If the argument x is not itself a Matcher, 25 | // this is equivalent to Contains(Equals(x)). 26 | func Contains(x any) Matcher { 27 | var result containsMatcher 28 | var ok bool 29 | 30 | if result.elementMatcher, ok = x.(Matcher); !ok { 31 | result.elementMatcher = DeepEquals(x) 32 | } 33 | 34 | return &result 35 | } 36 | 37 | type containsMatcher struct { 38 | elementMatcher Matcher 39 | } 40 | 41 | func (m *containsMatcher) Description() string { 42 | return fmt.Sprintf("contains: %s", m.elementMatcher.Description()) 43 | } 44 | 45 | func (m *containsMatcher) Matches(candidate any) error { 46 | // The candidate must be a slice or an array. 47 | v := reflect.ValueOf(candidate) 48 | if v.Kind() != reflect.Slice && v.Kind() != reflect.Array { 49 | return NewFatalError("which is not a slice or array") 50 | } 51 | 52 | // Check each element. 53 | for i := 0; i < v.Len(); i++ { 54 | elem := v.Index(i) 55 | if matchErr := m.elementMatcher.Matches(elem.Interface()); matchErr == nil { 56 | return nil 57 | } 58 | } 59 | 60 | return fmt.Errorf("") 61 | } 62 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/internal/oglematchers/deep_equals.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | import ( 19 | "bytes" 20 | "errors" 21 | "fmt" 22 | "reflect" 23 | ) 24 | 25 | var byteSliceType reflect.Type = reflect.TypeOf([]byte{}) 26 | 27 | // DeepEquals returns a matcher that matches based on 'deep equality', as 28 | // defined by the reflect package. This matcher requires that values have 29 | // identical types to x. 30 | func DeepEquals(x any) Matcher { 31 | return &deepEqualsMatcher{x} 32 | } 33 | 34 | type deepEqualsMatcher struct { 35 | x any 36 | } 37 | 38 | func (m *deepEqualsMatcher) Description() string { 39 | xDesc := fmt.Sprintf("%v", m.x) 40 | xValue := reflect.ValueOf(m.x) 41 | 42 | // Special case: fmt.Sprintf presents nil slices as "[]", but 43 | // reflect.DeepEqual makes a distinction between nil and empty slices. Make 44 | // this less confusing. 45 | if xValue.Kind() == reflect.Slice && xValue.IsNil() { 46 | xDesc = "" 47 | } 48 | 49 | return fmt.Sprintf("deep equals: %s", xDesc) 50 | } 51 | 52 | func (m *deepEqualsMatcher) Matches(c any) error { 53 | // Make sure the types match. 54 | ct := reflect.TypeOf(c) 55 | xt := reflect.TypeOf(m.x) 56 | 57 | if ct != xt { 58 | return NewFatalError(fmt.Sprintf("which is of type %v", ct)) 59 | } 60 | 61 | // Special case: handle byte slices more efficiently. 62 | cValue := reflect.ValueOf(c) 63 | xValue := reflect.ValueOf(m.x) 64 | 65 | if ct == byteSliceType && !cValue.IsNil() && !xValue.IsNil() { 66 | xBytes := m.x.([]byte) 67 | cBytes := c.([]byte) 68 | 69 | if bytes.Equal(cBytes, xBytes) { 70 | return nil 71 | } 72 | 73 | return errors.New("") 74 | } 75 | 76 | // Defer to the reflect package. 77 | if reflect.DeepEqual(m.x, c) { 78 | return nil 79 | } 80 | 81 | // Special case: if the comparison failed because c is the nil slice, given 82 | // an indication of this (since its value is printed as "[]"). 83 | if cValue.Kind() == reflect.Slice && cValue.IsNil() { 84 | return errors.New("which is nil") 85 | } 86 | 87 | return errors.New("") 88 | } 89 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/internal/oglematchers/greater_or_equal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | import ( 19 | "fmt" 20 | "reflect" 21 | ) 22 | 23 | // GreaterOrEqual returns a matcher that matches integer, floating point, or 24 | // strings values v such that v >= x. Comparison is not defined between numeric 25 | // and string types, but is defined between all integer and floating point 26 | // types. 27 | // 28 | // x must itself be an integer, floating point, or string type; otherwise, 29 | // GreaterOrEqual will panic. 30 | func GreaterOrEqual(x any) Matcher { 31 | desc := fmt.Sprintf("greater than or equal to %v", x) 32 | 33 | // Special case: make it clear that strings are strings. 34 | if reflect.TypeOf(x).Kind() == reflect.String { 35 | desc = fmt.Sprintf("greater than or equal to \"%s\"", x) 36 | } 37 | 38 | return transformDescription(Not(LessThan(x)), desc) 39 | } 40 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/internal/oglematchers/greater_than.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | import ( 19 | "fmt" 20 | "reflect" 21 | ) 22 | 23 | // GreaterThan returns a matcher that matches integer, floating point, or 24 | // strings values v such that v > x. Comparison is not defined between numeric 25 | // and string types, but is defined between all integer and floating point 26 | // types. 27 | // 28 | // x must itself be an integer, floating point, or string type; otherwise, 29 | // GreaterThan will panic. 30 | func GreaterThan(x any) Matcher { 31 | desc := fmt.Sprintf("greater than %v", x) 32 | 33 | // Special case: make it clear that strings are strings. 34 | if reflect.TypeOf(x).Kind() == reflect.String { 35 | desc = fmt.Sprintf("greater than \"%s\"", x) 36 | } 37 | 38 | return transformDescription(Not(LessOrEqual(x)), desc) 39 | } 40 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/internal/oglematchers/less_or_equal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | import ( 19 | "fmt" 20 | "reflect" 21 | ) 22 | 23 | // LessOrEqual returns a matcher that matches integer, floating point, or 24 | // strings values v such that v <= x. Comparison is not defined between numeric 25 | // and string types, but is defined between all integer and floating point 26 | // types. 27 | // 28 | // x must itself be an integer, floating point, or string type; otherwise, 29 | // LessOrEqual will panic. 30 | func LessOrEqual(x any) Matcher { 31 | desc := fmt.Sprintf("less than or equal to %v", x) 32 | 33 | // Special case: make it clear that strings are strings. 34 | if reflect.TypeOf(x).Kind() == reflect.String { 35 | desc = fmt.Sprintf("less than or equal to \"%s\"", x) 36 | } 37 | 38 | // Put LessThan last so that its error messages will be used in the event of 39 | // failure. 40 | return transformDescription(AnyOf(Equals(x), LessThan(x)), desc) 41 | } 42 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/internal/oglematchers/not.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | import ( 19 | "errors" 20 | "fmt" 21 | ) 22 | 23 | // Not returns a matcher that inverts the set of values matched by the wrapped 24 | // matcher. It does not transform the result for values for which the wrapped 25 | // matcher returns a fatal error. 26 | func Not(m Matcher) Matcher { 27 | return ¬Matcher{m} 28 | } 29 | 30 | type notMatcher struct { 31 | wrapped Matcher 32 | } 33 | 34 | func (m *notMatcher) Matches(c any) (err error) { 35 | err = m.wrapped.Matches(c) 36 | 37 | // Did the wrapped matcher say yes? 38 | if err == nil { 39 | return errors.New("") 40 | } 41 | 42 | // Did the wrapped matcher return a fatal error? 43 | if _, isFatal := err.(*FatalError); isFatal { 44 | return err 45 | } 46 | 47 | // The wrapped matcher returned a non-fatal error. 48 | return nil 49 | } 50 | 51 | func (m *notMatcher) Description() string { 52 | return fmt.Sprintf("not(%s)", m.wrapped.Description()) 53 | } 54 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/internal/oglematchers/transform_description.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | // transformDescription returns a matcher that is equivalent to the supplied 19 | // one, except that it has the supplied description instead of the one attached 20 | // to the existing matcher. 21 | func transformDescription(m Matcher, newDesc string) Matcher { 22 | return &transformDescriptionMatcher{newDesc, m} 23 | } 24 | 25 | type transformDescriptionMatcher struct { 26 | desc string 27 | wrappedMatcher Matcher 28 | } 29 | 30 | func (m *transformDescriptionMatcher) Description() string { 31 | return m.desc 32 | } 33 | 34 | func (m *transformDescriptionMatcher) Matches(c any) error { 35 | return m.wrappedMatcher.Matches(c) 36 | } 37 | -------------------------------------------------------------------------------- /vendor/github.com/smarty/assertions/serializer.go: -------------------------------------------------------------------------------- 1 | package assertions 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "strings" 7 | 8 | "github.com/smarty/assertions/internal/go-render/render" 9 | ) 10 | 11 | type Serializer interface { 12 | serialize(expected, actual any, message string) string 13 | serializeDetailed(expected, actual any, message string) string 14 | } 15 | 16 | type failureSerializer struct{} 17 | 18 | func (self *failureSerializer) serializeDetailed(expected, actual any, message string) string { 19 | if index := strings.Index(message, " Diff:"); index > 0 { 20 | message = message[:index] 21 | } 22 | view := FailureView{ 23 | Message: message, 24 | Expected: render.Render(expected), 25 | Actual: render.Render(actual), 26 | } 27 | serialized, _ := json.Marshal(view) 28 | return string(serialized) 29 | } 30 | 31 | func (self *failureSerializer) serialize(expected, actual any, message string) string { 32 | if index := strings.Index(message, " Diff:"); index > 0 { 33 | message = message[:index] 34 | } 35 | view := FailureView{ 36 | Message: message, 37 | Expected: fmt.Sprintf("%+v", expected), 38 | Actual: fmt.Sprintf("%+v", actual), 39 | } 40 | serialized, _ := json.Marshal(view) 41 | return string(serialized) 42 | } 43 | 44 | func newSerializer() *failureSerializer { 45 | return &failureSerializer{} 46 | } 47 | 48 | /////////////////////////////////////////////////////////////////////////////// 49 | 50 | // FailureView is also declared in github.com/smarty/goconvey/convey/reporting. 51 | // The json struct tags should be equal in both declarations. 52 | type FailureView struct { 53 | Message string `json:"Message"` 54 | Expected string `json:"Expected"` 55 | Actual string `json:"Actual"` 56 | } 57 | 58 | /////////////////////////////////////////////////////// 59 | 60 | // noopSerializer just gives back the original message. This is useful when we are using 61 | // the assertions from a context other than the GoConvey Web UI, that requires the JSON 62 | // structure provided by the failureSerializer. 63 | type noopSerializer struct{} 64 | 65 | func (self *noopSerializer) serialize(expected, actual any, message string) string { 66 | return message 67 | } 68 | func (self *noopSerializer) serializeDetailed(expected, actual any, message string) string { 69 | return message 70 | } 71 | -------------------------------------------------------------------------------- /vendor/github.com/smartystreets/goconvey/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Smarty 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | NOTE: Various optional and subordinate components carry their own licensing 24 | requirements and restrictions. Use of those components is subject to the terms 25 | and conditions outlined the respective license of each component. 26 | -------------------------------------------------------------------------------- /vendor/github.com/smartystreets/goconvey/convey/convey.goconvey: -------------------------------------------------------------------------------- 1 | #ignore 2 | -timeout=1s 3 | #-covermode=count 4 | #-coverpkg=github.com/smartystreets/goconvey/convey,github.com/smartystreets/goconvey/convey/gotest,github.com/smartystreets/goconvey/convey/reporting -------------------------------------------------------------------------------- /vendor/github.com/smartystreets/goconvey/convey/gotest/utils.go: -------------------------------------------------------------------------------- 1 | // Package gotest contains internal functionality. Although this package 2 | // contains one or more exported names it is not intended for public 3 | // consumption. See the examples package for how to use this project. 4 | package gotest 5 | 6 | import ( 7 | "runtime" 8 | "strings" 9 | ) 10 | 11 | func ResolveExternalCaller() (file string, line int, name string) { 12 | var caller_id uintptr 13 | callers := runtime.Callers(0, callStack) 14 | 15 | for x := 0; x < callers; x++ { 16 | caller_id, file, line, _ = runtime.Caller(x) 17 | if strings.HasSuffix(file, "_test.go") || strings.HasSuffix(file, "_tests.go") { 18 | name = runtime.FuncForPC(caller_id).Name() 19 | return 20 | } 21 | } 22 | file, line, name = "", -1, "" 23 | return // panic? 24 | } 25 | 26 | const maxStackDepth = 100 // This had better be enough... 27 | 28 | var callStack []uintptr = make([]uintptr, maxStackDepth, maxStackDepth) 29 | -------------------------------------------------------------------------------- /vendor/github.com/smartystreets/goconvey/convey/init.go: -------------------------------------------------------------------------------- 1 | package convey 2 | 3 | import ( 4 | "flag" 5 | "os" 6 | 7 | "github.com/jtolds/gls" 8 | "github.com/smarty/assertions" 9 | "github.com/smartystreets/goconvey/convey/reporting" 10 | ) 11 | 12 | func init() { 13 | assertions.GoConveyMode(true) 14 | 15 | declareFlags() 16 | 17 | ctxMgr = gls.NewContextManager() 18 | } 19 | 20 | func declareFlags() { 21 | flag.BoolVar(&json, "convey-json", false, "When true, emits results in JSON blocks. Default: 'false'") 22 | flag.BoolVar(&silent, "convey-silent", false, "When true, all output from GoConvey is suppressed.") 23 | flag.BoolVar(&story, "convey-story", false, "When true, emits story output, otherwise emits dot output. When not provided, this flag mirrors the value of the '-test.v' flag") 24 | 25 | if noStoryFlagProvided() { 26 | story = verboseEnabled 27 | } 28 | 29 | // FYI: flag.Parse() is called from the testing package. 30 | } 31 | 32 | func noStoryFlagProvided() bool { 33 | return !story && !storyDisabled 34 | } 35 | 36 | func buildReporter() reporting.Reporter { 37 | selectReporter := os.Getenv("GOCONVEY_REPORTER") 38 | 39 | switch { 40 | case testReporter != nil: 41 | return testReporter 42 | case json || selectReporter == "json": 43 | return reporting.BuildJsonReporter() 44 | case silent || selectReporter == "silent": 45 | return reporting.BuildSilentReporter() 46 | case selectReporter == "dot": 47 | // Story is turned on when verbose is set, so we need to check for dot reporter first. 48 | return reporting.BuildDotReporter() 49 | case story || selectReporter == "story": 50 | return reporting.BuildStoryReporter() 51 | default: 52 | return reporting.BuildDotReporter() 53 | } 54 | } 55 | 56 | var ( 57 | ctxMgr *gls.ContextManager 58 | 59 | // only set by internal tests 60 | testReporter reporting.Reporter 61 | ) 62 | 63 | var ( 64 | json bool 65 | silent bool 66 | story bool 67 | 68 | verboseEnabled = flagFound("-test.v=true") 69 | storyDisabled = flagFound("-story=false") 70 | ) 71 | 72 | // flagFound parses the command line args manually for flags defined in other 73 | // packages. Like the '-v' flag from the "testing" package, for instance. 74 | func flagFound(flagValue string) bool { 75 | for _, arg := range os.Args { 76 | if arg == flagValue { 77 | return true 78 | } 79 | } 80 | return false 81 | } 82 | -------------------------------------------------------------------------------- /vendor/github.com/smartystreets/goconvey/convey/nilReporter.go: -------------------------------------------------------------------------------- 1 | package convey 2 | 3 | import ( 4 | "github.com/smartystreets/goconvey/convey/reporting" 5 | ) 6 | 7 | type nilReporter struct{} 8 | 9 | func (self *nilReporter) BeginStory(story *reporting.StoryReport) {} 10 | func (self *nilReporter) Enter(scope *reporting.ScopeReport) {} 11 | func (self *nilReporter) Report(report *reporting.AssertionResult) {} 12 | func (self *nilReporter) Exit() {} 13 | func (self *nilReporter) EndStory() {} 14 | func (self *nilReporter) Write(p []byte) (int, error) { return len(p), nil } 15 | func newNilReporter() *nilReporter { return &nilReporter{} } 16 | -------------------------------------------------------------------------------- /vendor/github.com/smartystreets/goconvey/convey/reporting/console.go: -------------------------------------------------------------------------------- 1 | package reporting 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | ) 7 | 8 | type console struct{} 9 | 10 | func (self *console) Write(p []byte) (n int, err error) { 11 | return fmt.Print(string(p)) 12 | } 13 | 14 | func NewConsole() io.Writer { 15 | return new(console) 16 | } 17 | -------------------------------------------------------------------------------- /vendor/github.com/smartystreets/goconvey/convey/reporting/doc.go: -------------------------------------------------------------------------------- 1 | // Package reporting contains internal functionality related 2 | // to console reporting and output. Although this package has 3 | // exported names is not intended for public consumption. See the 4 | // examples package for how to use this project. 5 | package reporting 6 | -------------------------------------------------------------------------------- /vendor/github.com/smartystreets/goconvey/convey/reporting/dot.go: -------------------------------------------------------------------------------- 1 | package reporting 2 | 3 | import "fmt" 4 | 5 | type dot struct{ out *Printer } 6 | 7 | func (self *dot) BeginStory(story *StoryReport) {} 8 | 9 | func (self *dot) Enter(scope *ScopeReport) {} 10 | 11 | func (self *dot) Report(report *AssertionResult) { 12 | if report.Error != nil { 13 | fmt.Print(redColor) 14 | self.out.Insert(dotError) 15 | } else if report.Failure != "" { 16 | fmt.Print(yellowColor) 17 | self.out.Insert(dotFailure) 18 | } else if report.Skipped { 19 | fmt.Print(yellowColor) 20 | self.out.Insert(dotSkip) 21 | } else { 22 | fmt.Print(greenColor) 23 | self.out.Insert(dotSuccess) 24 | } 25 | fmt.Print(resetColor) 26 | } 27 | 28 | func (self *dot) Exit() {} 29 | 30 | func (self *dot) EndStory() {} 31 | 32 | func (self *dot) Write(content []byte) (written int, err error) { 33 | return len(content), nil // no-op 34 | } 35 | 36 | func NewDotReporter(out *Printer) *dot { 37 | self := new(dot) 38 | self.out = out 39 | return self 40 | } 41 | -------------------------------------------------------------------------------- /vendor/github.com/smartystreets/goconvey/convey/reporting/gotest.go: -------------------------------------------------------------------------------- 1 | package reporting 2 | 3 | type gotestReporter struct{ test T } 4 | 5 | func (self *gotestReporter) BeginStory(story *StoryReport) { 6 | self.test = story.Test 7 | } 8 | 9 | func (self *gotestReporter) Enter(scope *ScopeReport) {} 10 | 11 | func (self *gotestReporter) Report(r *AssertionResult) { 12 | if !passed(r) { 13 | self.test.Fail() 14 | } 15 | } 16 | 17 | func (self *gotestReporter) Exit() {} 18 | 19 | func (self *gotestReporter) EndStory() { 20 | self.test = nil 21 | } 22 | 23 | func (self *gotestReporter) Write(content []byte) (written int, err error) { 24 | return len(content), nil // no-op 25 | } 26 | 27 | func NewGoTestReporter() *gotestReporter { 28 | return new(gotestReporter) 29 | } 30 | 31 | func passed(r *AssertionResult) bool { 32 | return r.Error == nil && r.Failure == "" 33 | } 34 | -------------------------------------------------------------------------------- /vendor/github.com/smartystreets/goconvey/convey/reporting/init.go: -------------------------------------------------------------------------------- 1 | package reporting 2 | 3 | import ( 4 | "os" 5 | "runtime" 6 | "strings" 7 | ) 8 | 9 | func init() { 10 | if !isColorableTerminal() { 11 | monochrome() 12 | } 13 | 14 | if runtime.GOOS == "windows" { 15 | success, failure, error_ = dotSuccess, dotFailure, dotError 16 | } 17 | } 18 | 19 | func BuildJsonReporter() Reporter { 20 | out := NewPrinter(NewConsole()) 21 | return NewReporters( 22 | NewGoTestReporter(), 23 | NewJsonReporter(out)) 24 | } 25 | func BuildDotReporter() Reporter { 26 | out := NewPrinter(NewConsole()) 27 | return NewReporters( 28 | NewGoTestReporter(), 29 | NewDotReporter(out), 30 | NewProblemReporter(out), 31 | consoleStatistics) 32 | } 33 | func BuildStoryReporter() Reporter { 34 | out := NewPrinter(NewConsole()) 35 | return NewReporters( 36 | NewGoTestReporter(), 37 | NewStoryReporter(out), 38 | NewProblemReporter(out), 39 | consoleStatistics) 40 | } 41 | func BuildSilentReporter() Reporter { 42 | out := NewPrinter(NewConsole()) 43 | return NewReporters( 44 | NewGoTestReporter(), 45 | NewSilentProblemReporter(out)) 46 | } 47 | 48 | var ( 49 | newline = "\n" 50 | success = "✔" 51 | failure = "✘" 52 | error_ = "🔥" 53 | skip = "⚠" 54 | dotSuccess = "." 55 | dotFailure = "x" 56 | dotError = "E" 57 | dotSkip = "S" 58 | errorTemplate = "* %s \nLine %d: - %v \n%s\n" 59 | failureTemplate = "* %s \nLine %d:\n%s\n" 60 | stackTemplate = "%s\n" 61 | ) 62 | 63 | var ( 64 | greenColor = "\033[32m" 65 | yellowColor = "\033[33m" 66 | redColor = "\033[31m" 67 | resetColor = "\033[0m" 68 | ) 69 | 70 | var consoleStatistics = NewStatisticsReporter(NewPrinter(NewConsole())) 71 | 72 | func SuppressConsoleStatistics() { consoleStatistics.Suppress() } 73 | func PrintConsoleStatistics() { consoleStatistics.PrintSummary() } 74 | 75 | // QuietMode disables all console output symbols. This is only meant to be used 76 | // for tests that are internal to goconvey where the output is distracting or 77 | // otherwise not needed in the test output. 78 | func QuietMode() { 79 | success, failure, error_, skip, dotSuccess, dotFailure, dotError, dotSkip = "", "", "", "", "", "", "", "" 80 | } 81 | 82 | func monochrome() { 83 | greenColor, yellowColor, redColor, resetColor = "", "", "", "" 84 | } 85 | 86 | func isColorableTerminal() bool { 87 | return strings.Contains(os.Getenv("TERM"), "color") 88 | } 89 | 90 | // This interface allows us to pass the *testing.T struct 91 | // throughout the internals of this tool without ever 92 | // having to import the "testing" package. 93 | type T interface { 94 | Fail() 95 | } 96 | -------------------------------------------------------------------------------- /vendor/github.com/smartystreets/goconvey/convey/reporting/json.go: -------------------------------------------------------------------------------- 1 | // TODO: under unit test 2 | 3 | package reporting 4 | 5 | import ( 6 | "bytes" 7 | "encoding/json" 8 | "fmt" 9 | "strings" 10 | ) 11 | 12 | type JsonReporter struct { 13 | out *Printer 14 | currentKey []string 15 | current *ScopeResult 16 | index map[string]*ScopeResult 17 | scopes []*ScopeResult 18 | } 19 | 20 | func (self *JsonReporter) depth() int { return len(self.currentKey) } 21 | 22 | func (self *JsonReporter) BeginStory(story *StoryReport) {} 23 | 24 | func (self *JsonReporter) Enter(scope *ScopeReport) { 25 | self.currentKey = append(self.currentKey, scope.Title) 26 | ID := strings.Join(self.currentKey, "|") 27 | if _, found := self.index[ID]; !found { 28 | next := newScopeResult(scope.Title, self.depth(), scope.File, scope.Line) 29 | self.scopes = append(self.scopes, next) 30 | self.index[ID] = next 31 | } 32 | self.current = self.index[ID] 33 | } 34 | 35 | func (self *JsonReporter) Report(report *AssertionResult) { 36 | self.current.Assertions = append(self.current.Assertions, report) 37 | } 38 | 39 | func (self *JsonReporter) Exit() { 40 | self.currentKey = self.currentKey[:len(self.currentKey)-1] 41 | } 42 | 43 | func (self *JsonReporter) EndStory() { 44 | self.report() 45 | self.reset() 46 | } 47 | func (self *JsonReporter) report() { 48 | scopes := []string{} 49 | for _, scope := range self.scopes { 50 | serialized, err := json.Marshal(scope) 51 | if err != nil { 52 | self.out.Println(jsonMarshalFailure) 53 | panic(err) 54 | } 55 | var buffer bytes.Buffer 56 | json.Indent(&buffer, serialized, "", " ") 57 | scopes = append(scopes, buffer.String()) 58 | } 59 | self.out.Print(fmt.Sprintf("%s\n%s,\n%s\n", OpenJson, strings.Join(scopes, ","), CloseJson)) 60 | } 61 | func (self *JsonReporter) reset() { 62 | self.scopes = []*ScopeResult{} 63 | self.index = map[string]*ScopeResult{} 64 | self.currentKey = nil 65 | } 66 | 67 | func (self *JsonReporter) Write(content []byte) (written int, err error) { 68 | self.current.Output += string(content) 69 | return len(content), nil 70 | } 71 | 72 | func NewJsonReporter(out *Printer) *JsonReporter { 73 | self := new(JsonReporter) 74 | self.out = out 75 | self.reset() 76 | return self 77 | } 78 | 79 | const OpenJson = ">->->OPEN-JSON->->->" // "⌦" 80 | const CloseJson = "<-<-<-CLOSE-JSON<-<-<" // "⌫" 81 | const jsonMarshalFailure = ` 82 | 83 | GOCONVEY_JSON_MARSHALL_FAILURE: There was an error when attempting to convert test results to JSON. 84 | Please file a bug report and reference the code that caused this failure if possible. 85 | 86 | Here's the panic: 87 | 88 | ` 89 | -------------------------------------------------------------------------------- /vendor/github.com/smartystreets/goconvey/convey/reporting/printer.go: -------------------------------------------------------------------------------- 1 | package reporting 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "strings" 7 | ) 8 | 9 | type Printer struct { 10 | out io.Writer 11 | prefix string 12 | } 13 | 14 | func (self *Printer) Println(message string, values ...any) { 15 | formatted := self.format(message, values...) + newline 16 | self.out.Write([]byte(formatted)) 17 | } 18 | 19 | func (self *Printer) Print(message string, values ...any) { 20 | formatted := self.format(message, values...) 21 | self.out.Write([]byte(formatted)) 22 | } 23 | 24 | func (self *Printer) Insert(text string) { 25 | self.out.Write([]byte(text)) 26 | } 27 | 28 | func (self *Printer) format(message string, values ...any) string { 29 | var formatted string 30 | if len(values) == 0 { 31 | formatted = self.prefix + message 32 | } else { 33 | formatted = self.prefix + fmt_Sprintf(message, values...) 34 | } 35 | indented := strings.Replace(formatted, newline, newline+self.prefix, -1) 36 | return strings.TrimRight(indented, space) 37 | } 38 | 39 | // Extracting fmt.Sprintf to a separate variable circumvents go vet, which, as of go 1.10 is run with go test. 40 | var fmt_Sprintf = fmt.Sprintf 41 | 42 | func (self *Printer) Indent() { 43 | self.prefix += pad 44 | } 45 | 46 | func (self *Printer) Dedent() { 47 | if len(self.prefix) >= padLength { 48 | self.prefix = self.prefix[:len(self.prefix)-padLength] 49 | } 50 | } 51 | 52 | func NewPrinter(out io.Writer) *Printer { 53 | self := new(Printer) 54 | self.out = out 55 | return self 56 | } 57 | 58 | const space = " " 59 | const pad = space + space 60 | const padLength = len(pad) 61 | -------------------------------------------------------------------------------- /vendor/github.com/smartystreets/goconvey/convey/reporting/problems.go: -------------------------------------------------------------------------------- 1 | package reporting 2 | 3 | import "fmt" 4 | 5 | type problem struct { 6 | silent bool 7 | out *Printer 8 | errors []*AssertionResult 9 | failures []*AssertionResult 10 | } 11 | 12 | func (self *problem) BeginStory(story *StoryReport) {} 13 | 14 | func (self *problem) Enter(scope *ScopeReport) {} 15 | 16 | func (self *problem) Report(report *AssertionResult) { 17 | if report.Error != nil { 18 | self.errors = append(self.errors, report) 19 | } else if report.Failure != "" { 20 | self.failures = append(self.failures, report) 21 | } 22 | } 23 | 24 | func (self *problem) Exit() {} 25 | 26 | func (self *problem) EndStory() { 27 | self.show(self.showErrors, redColor) 28 | self.show(self.showFailures, yellowColor) 29 | self.prepareForNextStory() 30 | } 31 | func (self *problem) show(display func(), color string) { 32 | if !self.silent { 33 | fmt.Print(color) 34 | } 35 | display() 36 | if !self.silent { 37 | fmt.Print(resetColor) 38 | } 39 | self.out.Dedent() 40 | } 41 | func (self *problem) showErrors() { 42 | for i, e := range self.errors { 43 | if i == 0 { 44 | self.out.Println("\nErrors:\n") 45 | self.out.Indent() 46 | } 47 | self.out.Println(errorTemplate, e.File, e.Line, e.Error, e.StackTrace) 48 | } 49 | } 50 | func (self *problem) showFailures() { 51 | for i, f := range self.failures { 52 | if i == 0 { 53 | self.out.Println("\nFailures:\n") 54 | self.out.Indent() 55 | } 56 | self.out.Println(failureTemplate, f.File, f.Line, f.Failure) 57 | if f.StackTrace != "" { 58 | self.out.Println(stackTemplate, f.StackTrace) 59 | } 60 | } 61 | } 62 | 63 | func (self *problem) Write(content []byte) (written int, err error) { 64 | return len(content), nil // no-op 65 | } 66 | 67 | func NewProblemReporter(out *Printer) *problem { 68 | self := new(problem) 69 | self.out = out 70 | self.prepareForNextStory() 71 | return self 72 | } 73 | 74 | func NewSilentProblemReporter(out *Printer) *problem { 75 | self := NewProblemReporter(out) 76 | self.silent = true 77 | return self 78 | } 79 | 80 | func (self *problem) prepareForNextStory() { 81 | self.errors = []*AssertionResult{} 82 | self.failures = []*AssertionResult{} 83 | } 84 | -------------------------------------------------------------------------------- /vendor/github.com/smartystreets/goconvey/convey/reporting/reporter.go: -------------------------------------------------------------------------------- 1 | package reporting 2 | 3 | import "io" 4 | 5 | type Reporter interface { 6 | BeginStory(story *StoryReport) 7 | Enter(scope *ScopeReport) 8 | Report(r *AssertionResult) 9 | Exit() 10 | EndStory() 11 | io.Writer 12 | } 13 | 14 | type reporters struct{ collection []Reporter } 15 | 16 | func (self *reporters) BeginStory(s *StoryReport) { self.foreach(func(r Reporter) { r.BeginStory(s) }) } 17 | func (self *reporters) Enter(s *ScopeReport) { self.foreach(func(r Reporter) { r.Enter(s) }) } 18 | func (self *reporters) Report(a *AssertionResult) { self.foreach(func(r Reporter) { r.Report(a) }) } 19 | func (self *reporters) Exit() { self.foreach(func(r Reporter) { r.Exit() }) } 20 | func (self *reporters) EndStory() { self.foreach(func(r Reporter) { r.EndStory() }) } 21 | 22 | func (self *reporters) Write(contents []byte) (written int, err error) { 23 | self.foreach(func(r Reporter) { 24 | written, err = r.Write(contents) 25 | }) 26 | return written, err 27 | } 28 | 29 | func (self *reporters) foreach(action func(Reporter)) { 30 | for _, r := range self.collection { 31 | action(r) 32 | } 33 | } 34 | 35 | func NewReporters(collection ...Reporter) *reporters { 36 | self := new(reporters) 37 | self.collection = collection 38 | return self 39 | } 40 | -------------------------------------------------------------------------------- /vendor/github.com/smartystreets/goconvey/convey/reporting/reporting.goconvey: -------------------------------------------------------------------------------- 1 | #ignore 2 | -timeout=1s 3 | -------------------------------------------------------------------------------- /vendor/github.com/smartystreets/goconvey/convey/reporting/statistics.go: -------------------------------------------------------------------------------- 1 | package reporting 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | func (self *statistics) BeginStory(story *StoryReport) {} 9 | 10 | func (self *statistics) Enter(scope *ScopeReport) {} 11 | 12 | func (self *statistics) Report(report *AssertionResult) { 13 | self.Lock() 14 | defer self.Unlock() 15 | 16 | if !self.failing && report.Failure != "" { 17 | self.failing = true 18 | } 19 | if !self.erroring && report.Error != nil { 20 | self.erroring = true 21 | } 22 | if report.Skipped { 23 | self.skipped += 1 24 | } else { 25 | self.total++ 26 | } 27 | } 28 | 29 | func (self *statistics) Exit() {} 30 | 31 | func (self *statistics) EndStory() { 32 | self.Lock() 33 | defer self.Unlock() 34 | 35 | if !self.suppressed { 36 | self.printSummaryLocked() 37 | } 38 | } 39 | 40 | func (self *statistics) Suppress() { 41 | self.Lock() 42 | defer self.Unlock() 43 | self.suppressed = true 44 | } 45 | 46 | func (self *statistics) PrintSummary() { 47 | self.Lock() 48 | defer self.Unlock() 49 | self.printSummaryLocked() 50 | } 51 | 52 | func (self *statistics) printSummaryLocked() { 53 | self.reportAssertionsLocked() 54 | self.reportSkippedSectionsLocked() 55 | self.completeReportLocked() 56 | } 57 | func (self *statistics) reportAssertionsLocked() { 58 | self.decideColorLocked() 59 | self.out.Print("\n%d total %s", self.total, plural("assertion", self.total)) 60 | } 61 | func (self *statistics) decideColorLocked() { 62 | if self.failing && !self.erroring { 63 | fmt.Print(yellowColor) 64 | } else if self.erroring { 65 | fmt.Print(redColor) 66 | } else { 67 | fmt.Print(greenColor) 68 | } 69 | } 70 | func (self *statistics) reportSkippedSectionsLocked() { 71 | if self.skipped > 0 { 72 | fmt.Print(yellowColor) 73 | self.out.Print(" (one or more sections skipped)") 74 | } 75 | } 76 | func (self *statistics) completeReportLocked() { 77 | fmt.Print(resetColor) 78 | self.out.Print("\n") 79 | self.out.Print("\n") 80 | } 81 | 82 | func (self *statistics) Write(content []byte) (written int, err error) { 83 | return len(content), nil // no-op 84 | } 85 | 86 | func NewStatisticsReporter(out *Printer) *statistics { 87 | self := statistics{} 88 | self.out = out 89 | return &self 90 | } 91 | 92 | type statistics struct { 93 | sync.Mutex 94 | 95 | out *Printer 96 | total int 97 | failing bool 98 | erroring bool 99 | skipped int 100 | suppressed bool 101 | } 102 | 103 | func plural(word string, count int) string { 104 | if count == 1 { 105 | return word 106 | } 107 | return word + "s" 108 | } 109 | -------------------------------------------------------------------------------- /vendor/github.com/smartystreets/goconvey/convey/reporting/story.go: -------------------------------------------------------------------------------- 1 | // TODO: in order for this reporter to be completely honest 2 | // we need to retrofit to be more like the json reporter such that: 3 | // 1. it maintains ScopeResult collections, which count assertions 4 | // 2. it reports only after EndStory(), so that all tick marks 5 | // are placed near the appropriate title. 6 | // 3. Under unit test 7 | 8 | package reporting 9 | 10 | import ( 11 | "fmt" 12 | "strings" 13 | ) 14 | 15 | type story struct { 16 | out *Printer 17 | titlesById map[string]string 18 | currentKey []string 19 | } 20 | 21 | func (self *story) BeginStory(story *StoryReport) {} 22 | 23 | func (self *story) Enter(scope *ScopeReport) { 24 | self.out.Indent() 25 | 26 | self.currentKey = append(self.currentKey, scope.Title) 27 | ID := strings.Join(self.currentKey, "|") 28 | 29 | if _, found := self.titlesById[ID]; !found { 30 | self.out.Println("") 31 | self.out.Print(scope.Title) 32 | self.out.Insert(" ") 33 | self.titlesById[ID] = scope.Title 34 | } 35 | } 36 | 37 | func (self *story) Report(report *AssertionResult) { 38 | if report.Error != nil { 39 | fmt.Print(redColor) 40 | self.out.Insert(error_) 41 | } else if report.Failure != "" { 42 | fmt.Print(yellowColor) 43 | self.out.Insert(failure) 44 | } else if report.Skipped { 45 | fmt.Print(yellowColor) 46 | self.out.Insert(skip) 47 | } else { 48 | fmt.Print(greenColor) 49 | self.out.Insert(success) 50 | } 51 | fmt.Print(resetColor) 52 | } 53 | 54 | func (self *story) Exit() { 55 | self.out.Dedent() 56 | self.currentKey = self.currentKey[:len(self.currentKey)-1] 57 | } 58 | 59 | func (self *story) EndStory() { 60 | self.titlesById = make(map[string]string) 61 | self.out.Println("\n") 62 | } 63 | 64 | func (self *story) Write(content []byte) (written int, err error) { 65 | return len(content), nil // no-op 66 | } 67 | 68 | func NewStoryReporter(out *Printer) *story { 69 | self := new(story) 70 | self.out = out 71 | self.titlesById = make(map[string]string) 72 | return self 73 | } 74 | -------------------------------------------------------------------------------- /vendor/github.com/smartystreets/goconvey/convey/update_assertions.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | cd "$(dirname $(realpath $0))" 4 | 5 | ASSERTIONS=($( 6 | go tool nm "$(go list -export -f '{{.Export}}' github.com/smarty/assertions)" |\ 7 | awk '/ T github\.com\/smarty\/assertions\.Should/{split($3, a, "."); print a[3]}' |\ 8 | sort | uniq)) 9 | 10 | ( 11 | echo "package convey" 12 | echo 13 | echo "// DO NOT EDIT: generated by update_assertions.sh" 14 | echo 15 | echo "//go:generate ./update_assertions.sh" 16 | echo 17 | echo "import \"github.com/smarty/assertions\"" 18 | echo 19 | echo "// These assertions are forwarded from github.com/smarty/assertions" 20 | echo "// in order to make convey self-contained." 21 | echo "var (" 22 | 23 | for assertion in "${ASSERTIONS[@]}" 24 | do 25 | echo " $assertion = assertions.$assertion" 26 | done 27 | 28 | echo ")" 29 | ) > ./assertions.go 30 | 31 | go fmt ./assertions.go 32 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/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/sys/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/sys/windows/aliases.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 | //go:build windows && go1.9 6 | 7 | package windows 8 | 9 | import "syscall" 10 | 11 | type Errno = syscall.Errno 12 | type SysProcAttr = syscall.SysProcAttr 13 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/windows/empty.s: -------------------------------------------------------------------------------- 1 | // Copyright 2019 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:build !go1.12 6 | 7 | // This file is here to allow bodyless functions with go:linkname for Go 1.11 8 | // and earlier (see https://golang.org/issue/23311). 9 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/windows/env_windows.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 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 | // Windows environment variables. 6 | 7 | package windows 8 | 9 | import ( 10 | "syscall" 11 | "unsafe" 12 | ) 13 | 14 | func Getenv(key string) (value string, found bool) { 15 | return syscall.Getenv(key) 16 | } 17 | 18 | func Setenv(key, value string) error { 19 | return syscall.Setenv(key, value) 20 | } 21 | 22 | func Clearenv() { 23 | syscall.Clearenv() 24 | } 25 | 26 | func Environ() []string { 27 | return syscall.Environ() 28 | } 29 | 30 | // Returns a default environment associated with the token, rather than the current 31 | // process. If inheritExisting is true, then this environment also inherits the 32 | // environment of the current process. 33 | func (token Token) Environ(inheritExisting bool) (env []string, err error) { 34 | var block *uint16 35 | err = CreateEnvironmentBlock(&block, token, inheritExisting) 36 | if err != nil { 37 | return nil, err 38 | } 39 | defer DestroyEnvironmentBlock(block) 40 | size := unsafe.Sizeof(*block) 41 | for *block != 0 { 42 | // find NUL terminator 43 | end := unsafe.Pointer(block) 44 | for *(*uint16)(end) != 0 { 45 | end = unsafe.Add(end, size) 46 | } 47 | 48 | entry := unsafe.Slice(block, (uintptr(end)-uintptr(unsafe.Pointer(block)))/size) 49 | env = append(env, UTF16ToString(entry)) 50 | block = (*uint16)(unsafe.Add(end, size)) 51 | } 52 | return env, nil 53 | } 54 | 55 | func Unsetenv(key string) error { 56 | return syscall.Unsetenv(key) 57 | } 58 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/windows/eventlog.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 | //go:build windows 6 | 7 | package windows 8 | 9 | const ( 10 | EVENTLOG_SUCCESS = 0 11 | EVENTLOG_ERROR_TYPE = 1 12 | EVENTLOG_WARNING_TYPE = 2 13 | EVENTLOG_INFORMATION_TYPE = 4 14 | EVENTLOG_AUDIT_SUCCESS = 8 15 | EVENTLOG_AUDIT_FAILURE = 16 16 | ) 17 | 18 | //sys RegisterEventSource(uncServerName *uint16, sourceName *uint16) (handle Handle, err error) [failretval==0] = advapi32.RegisterEventSourceW 19 | //sys DeregisterEventSource(handle Handle) (err error) = advapi32.DeregisterEventSource 20 | //sys ReportEvent(log Handle, etype uint16, category uint16, eventId uint32, usrSId uintptr, numStrings uint16, dataSize uint32, strings **uint16, rawData *byte) (err error) = advapi32.ReportEventW 21 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/windows/memory_windows.go: -------------------------------------------------------------------------------- 1 | // Copyright 2017 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 windows 6 | 7 | const ( 8 | MEM_COMMIT = 0x00001000 9 | MEM_RESERVE = 0x00002000 10 | MEM_DECOMMIT = 0x00004000 11 | MEM_RELEASE = 0x00008000 12 | MEM_RESET = 0x00080000 13 | MEM_TOP_DOWN = 0x00100000 14 | MEM_WRITE_WATCH = 0x00200000 15 | MEM_PHYSICAL = 0x00400000 16 | MEM_RESET_UNDO = 0x01000000 17 | MEM_LARGE_PAGES = 0x20000000 18 | 19 | PAGE_NOACCESS = 0x00000001 20 | PAGE_READONLY = 0x00000002 21 | PAGE_READWRITE = 0x00000004 22 | PAGE_WRITECOPY = 0x00000008 23 | PAGE_EXECUTE = 0x00000010 24 | PAGE_EXECUTE_READ = 0x00000020 25 | PAGE_EXECUTE_READWRITE = 0x00000040 26 | PAGE_EXECUTE_WRITECOPY = 0x00000080 27 | PAGE_GUARD = 0x00000100 28 | PAGE_NOCACHE = 0x00000200 29 | PAGE_WRITECOMBINE = 0x00000400 30 | PAGE_TARGETS_INVALID = 0x40000000 31 | PAGE_TARGETS_NO_UPDATE = 0x40000000 32 | 33 | QUOTA_LIMITS_HARDWS_MIN_DISABLE = 0x00000002 34 | QUOTA_LIMITS_HARDWS_MIN_ENABLE = 0x00000001 35 | QUOTA_LIMITS_HARDWS_MAX_DISABLE = 0x00000008 36 | QUOTA_LIMITS_HARDWS_MAX_ENABLE = 0x00000004 37 | ) 38 | 39 | type MemoryBasicInformation struct { 40 | BaseAddress uintptr 41 | AllocationBase uintptr 42 | AllocationProtect uint32 43 | PartitionId uint16 44 | RegionSize uintptr 45 | State uint32 46 | Protect uint32 47 | Type uint32 48 | } 49 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/windows/mkerrors.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2019 The Go Authors. All rights reserved. 4 | # Use of this source code is governed by a BSD-style 5 | # license that can be found in the LICENSE file. 6 | 7 | set -e 8 | shopt -s nullglob 9 | 10 | winerror="$(printf '%s\n' "/mnt/c/Program Files (x86)/Windows Kits/"/*/Include/*/shared/winerror.h | sort -Vr | head -n 1)" 11 | [[ -n $winerror ]] || { echo "Unable to find winerror.h" >&2; exit 1; } 12 | ntstatus="$(printf '%s\n' "/mnt/c/Program Files (x86)/Windows Kits/"/*/Include/*/shared/ntstatus.h | sort -Vr | head -n 1)" 13 | [[ -n $ntstatus ]] || { echo "Unable to find ntstatus.h" >&2; exit 1; } 14 | 15 | declare -A errors 16 | 17 | { 18 | echo "// Code generated by 'mkerrors.bash'; DO NOT EDIT." 19 | echo 20 | echo "package windows" 21 | echo "import \"syscall\"" 22 | echo "const (" 23 | 24 | while read -r line; do 25 | unset vtype 26 | if [[ $line =~ ^#define\ +([A-Z0-9_]+k?)\ +([A-Z0-9_]+\()?([A-Z][A-Z0-9_]+k?)\)? ]]; then 27 | key="${BASH_REMATCH[1]}" 28 | value="${BASH_REMATCH[3]}" 29 | elif [[ $line =~ ^#define\ +([A-Z0-9_]+k?)\ +([A-Z0-9_]+\()?((0x)?[0-9A-Fa-f]+)L?\)? ]]; then 30 | key="${BASH_REMATCH[1]}" 31 | value="${BASH_REMATCH[3]}" 32 | vtype="${BASH_REMATCH[2]}" 33 | elif [[ $line =~ ^#define\ +([A-Z0-9_]+k?)\ +\(\(([A-Z]+)\)((0x)?[0-9A-Fa-f]+)L?\) ]]; then 34 | key="${BASH_REMATCH[1]}" 35 | value="${BASH_REMATCH[3]}" 36 | vtype="${BASH_REMATCH[2]}" 37 | else 38 | continue 39 | fi 40 | [[ -n $key && -n $value ]] || continue 41 | [[ -z ${errors["$key"]} ]] || continue 42 | errors["$key"]="$value" 43 | if [[ -v vtype ]]; then 44 | if [[ $key == FACILITY_* || $key == NO_ERROR ]]; then 45 | vtype="" 46 | elif [[ $vtype == *HANDLE* || $vtype == *HRESULT* ]]; then 47 | vtype="Handle" 48 | else 49 | vtype="syscall.Errno" 50 | fi 51 | last_vtype="$vtype" 52 | else 53 | vtype="" 54 | if [[ $last_vtype == Handle && $value == NO_ERROR ]]; then 55 | value="S_OK" 56 | elif [[ $last_vtype == syscall.Errno && $value == NO_ERROR ]]; then 57 | value="ERROR_SUCCESS" 58 | fi 59 | fi 60 | 61 | echo "$key $vtype = $value" 62 | done < "$winerror" 63 | 64 | while read -r line; do 65 | [[ $line =~ ^#define\ (STATUS_[^\s]+)\ +\(\(NTSTATUS\)((0x)?[0-9a-fA-F]+)L?\) ]] || continue 66 | echo "${BASH_REMATCH[1]} NTStatus = ${BASH_REMATCH[2]}" 67 | done < "$ntstatus" 68 | 69 | echo ")" 70 | } | gofmt > "zerrors_windows.go" 71 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/windows/mkknownfolderids.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2019 The Go Authors. All rights reserved. 4 | # Use of this source code is governed by a BSD-style 5 | # license that can be found in the LICENSE file. 6 | 7 | set -e 8 | shopt -s nullglob 9 | 10 | knownfolders="$(printf '%s\n' "/mnt/c/Program Files (x86)/Windows Kits/"/*/Include/*/um/KnownFolders.h | sort -Vr | head -n 1)" 11 | [[ -n $knownfolders ]] || { echo "Unable to find KnownFolders.h" >&2; exit 1; } 12 | 13 | { 14 | echo "// Code generated by 'mkknownfolderids.bash'; DO NOT EDIT." 15 | echo 16 | echo "package windows" 17 | echo "type KNOWNFOLDERID GUID" 18 | echo "var (" 19 | while read -r line; do 20 | [[ $line =~ DEFINE_KNOWN_FOLDER\((FOLDERID_[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+),[\t\ ]*(0x[^,]+)\) ]] || continue 21 | printf "%s = &KNOWNFOLDERID{0x%08x, 0x%04x, 0x%04x, [8]byte{0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x}}\n" \ 22 | "${BASH_REMATCH[1]}" $(( "${BASH_REMATCH[2]}" )) $(( "${BASH_REMATCH[3]}" )) $(( "${BASH_REMATCH[4]}" )) \ 23 | $(( "${BASH_REMATCH[5]}" )) $(( "${BASH_REMATCH[6]}" )) $(( "${BASH_REMATCH[7]}" )) $(( "${BASH_REMATCH[8]}" )) \ 24 | $(( "${BASH_REMATCH[9]}" )) $(( "${BASH_REMATCH[10]}" )) $(( "${BASH_REMATCH[11]}" )) $(( "${BASH_REMATCH[12]}" )) 25 | done < "$knownfolders" 26 | echo ")" 27 | } | gofmt > "zknownfolderids_windows.go" 28 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/windows/mksyscall.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 | 5 | //go:build generate 6 | 7 | package windows 8 | 9 | //go:generate go run golang.org/x/sys/windows/mkwinsyscall -output zsyscall_windows.go eventlog.go service.go syscall_windows.go security_windows.go setupapi_windows.go 10 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/windows/race.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 | //go:build windows && race 6 | 7 | package windows 8 | 9 | import ( 10 | "runtime" 11 | "unsafe" 12 | ) 13 | 14 | const raceenabled = true 15 | 16 | func raceAcquire(addr unsafe.Pointer) { 17 | runtime.RaceAcquire(addr) 18 | } 19 | 20 | func raceReleaseMerge(addr unsafe.Pointer) { 21 | runtime.RaceReleaseMerge(addr) 22 | } 23 | 24 | func raceReadRange(addr unsafe.Pointer, len int) { 25 | runtime.RaceReadRange(addr, len) 26 | } 27 | 28 | func raceWriteRange(addr unsafe.Pointer, len int) { 29 | runtime.RaceWriteRange(addr, len) 30 | } 31 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/windows/race0.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 | //go:build windows && !race 6 | 7 | package windows 8 | 9 | import ( 10 | "unsafe" 11 | ) 12 | 13 | const raceenabled = false 14 | 15 | func raceAcquire(addr unsafe.Pointer) { 16 | } 17 | 18 | func raceReleaseMerge(addr unsafe.Pointer) { 19 | } 20 | 21 | func raceReadRange(addr unsafe.Pointer, len int) { 22 | } 23 | 24 | func raceWriteRange(addr unsafe.Pointer, len int) { 25 | } 26 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/windows/str.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 | 5 | //go:build windows 6 | 7 | package windows 8 | 9 | func itoa(val int) string { // do it here rather than with fmt to avoid dependency 10 | if val < 0 { 11 | return "-" + itoa(-val) 12 | } 13 | var buf [32]byte // big enough for int64 14 | i := len(buf) - 1 15 | for val >= 10 { 16 | buf[i] = byte(val%10 + '0') 17 | i-- 18 | val /= 10 19 | } 20 | buf[i] = byte(val + '0') 21 | return string(buf[i:]) 22 | } 23 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/windows/types_windows_386.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 windows 6 | 7 | type WSAData struct { 8 | Version uint16 9 | HighVersion uint16 10 | Description [WSADESCRIPTION_LEN + 1]byte 11 | SystemStatus [WSASYS_STATUS_LEN + 1]byte 12 | MaxSockets uint16 13 | MaxUdpDg uint16 14 | VendorInfo *byte 15 | } 16 | 17 | type Servent struct { 18 | Name *byte 19 | Aliases **byte 20 | Port uint16 21 | Proto *byte 22 | } 23 | 24 | type JOBOBJECT_BASIC_LIMIT_INFORMATION struct { 25 | PerProcessUserTimeLimit int64 26 | PerJobUserTimeLimit int64 27 | LimitFlags uint32 28 | MinimumWorkingSetSize uintptr 29 | MaximumWorkingSetSize uintptr 30 | ActiveProcessLimit uint32 31 | Affinity uintptr 32 | PriorityClass uint32 33 | SchedulingClass uint32 34 | _ uint32 // pad to 8 byte boundary 35 | } 36 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/windows/types_windows_amd64.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 windows 6 | 7 | type WSAData struct { 8 | Version uint16 9 | HighVersion uint16 10 | MaxSockets uint16 11 | MaxUdpDg uint16 12 | VendorInfo *byte 13 | Description [WSADESCRIPTION_LEN + 1]byte 14 | SystemStatus [WSASYS_STATUS_LEN + 1]byte 15 | } 16 | 17 | type Servent struct { 18 | Name *byte 19 | Aliases **byte 20 | Proto *byte 21 | Port uint16 22 | } 23 | 24 | type JOBOBJECT_BASIC_LIMIT_INFORMATION struct { 25 | PerProcessUserTimeLimit int64 26 | PerJobUserTimeLimit int64 27 | LimitFlags uint32 28 | MinimumWorkingSetSize uintptr 29 | MaximumWorkingSetSize uintptr 30 | ActiveProcessLimit uint32 31 | Affinity uintptr 32 | PriorityClass uint32 33 | SchedulingClass uint32 34 | } 35 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/windows/types_windows_arm.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 windows 6 | 7 | type WSAData struct { 8 | Version uint16 9 | HighVersion uint16 10 | Description [WSADESCRIPTION_LEN + 1]byte 11 | SystemStatus [WSASYS_STATUS_LEN + 1]byte 12 | MaxSockets uint16 13 | MaxUdpDg uint16 14 | VendorInfo *byte 15 | } 16 | 17 | type Servent struct { 18 | Name *byte 19 | Aliases **byte 20 | Port uint16 21 | Proto *byte 22 | } 23 | 24 | type JOBOBJECT_BASIC_LIMIT_INFORMATION struct { 25 | PerProcessUserTimeLimit int64 26 | PerJobUserTimeLimit int64 27 | LimitFlags uint32 28 | MinimumWorkingSetSize uintptr 29 | MaximumWorkingSetSize uintptr 30 | ActiveProcessLimit uint32 31 | Affinity uintptr 32 | PriorityClass uint32 33 | SchedulingClass uint32 34 | _ uint32 // pad to 8 byte boundary 35 | } 36 | -------------------------------------------------------------------------------- /vendor/golang.org/x/sys/windows/types_windows_arm64.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 windows 6 | 7 | type WSAData struct { 8 | Version uint16 9 | HighVersion uint16 10 | MaxSockets uint16 11 | MaxUdpDg uint16 12 | VendorInfo *byte 13 | Description [WSADESCRIPTION_LEN + 1]byte 14 | SystemStatus [WSASYS_STATUS_LEN + 1]byte 15 | } 16 | 17 | type Servent struct { 18 | Name *byte 19 | Aliases **byte 20 | Proto *byte 21 | Port uint16 22 | } 23 | 24 | type JOBOBJECT_BASIC_LIMIT_INFORMATION struct { 25 | PerProcessUserTimeLimit int64 26 | PerJobUserTimeLimit int64 27 | LimitFlags uint32 28 | MinimumWorkingSetSize uintptr 29 | MaximumWorkingSetSize uintptr 30 | ActiveProcessLimit uint32 31 | Affinity uintptr 32 | PriorityClass uint32 33 | SchedulingClass uint32 34 | } 35 | -------------------------------------------------------------------------------- /vendor/modules.txt: -------------------------------------------------------------------------------- 1 | # github.com/google/gopacket v1.1.19 2 | ## explicit; go 1.12 3 | github.com/google/gopacket 4 | github.com/google/gopacket/layers 5 | github.com/google/gopacket/pcap 6 | # github.com/gopherjs/gopherjs v1.17.2 7 | ## explicit; go 1.17 8 | github.com/gopherjs/gopherjs/js 9 | # github.com/jtolds/gls v4.20.0+incompatible 10 | ## explicit 11 | github.com/jtolds/gls 12 | # github.com/smarty/assertions v1.15.0 13 | ## explicit; go 1.18 14 | github.com/smarty/assertions 15 | github.com/smarty/assertions/internal/go-diff/diffmatchpatch 16 | github.com/smarty/assertions/internal/go-render/render 17 | github.com/smarty/assertions/internal/oglematchers 18 | # github.com/smartystreets/goconvey v1.8.1 19 | ## explicit; go 1.18 20 | github.com/smartystreets/goconvey/convey 21 | github.com/smartystreets/goconvey/convey/gotest 22 | github.com/smartystreets/goconvey/convey/reporting 23 | # golang.org/x/net v0.23.0 24 | ## explicit; go 1.18 25 | # golang.org/x/sys v0.18.0 26 | ## explicit; go 1.18 27 | golang.org/x/sys/windows 28 | --------------------------------------------------------------------------------