From eb43ff69c4f250fe7fd2c33f1202ae5349782ec8 Mon Sep 17 00:00:00 2001 From: cloudfodder Date: Tue, 28 Jul 2026 10:42:09 -0700 Subject: [PATCH] feat(nostr): nostr-based account registration and verification Rebuilt the nostr registration feature cleanly on top of current ergo mainline (origin/master), dropping the stale ergo reversions that were entangled in the original squashed branch. - New irc/nostr package: NIP-04/NIP-17 DMs, NIP-05 resolution, relay connect/auth, and identifier helpers. - Registration/verification via nostr: parseCallback auto-detects nostr identifiers (NIP-05, npub, hex pubkey) and dispatches a verification DM. - Nostr-based cloaked hostnames for accounts (opt-in via ip-cloaking.nostr-hostnames), applied at the account-cloak sites. - Config: accounts.registration.nostr-verification and the nostr-hostnames cloak option, with matching default.yaml and help text. - Adds github.com/nbd-wtf/go-nostr and vendored dependencies. --- default.yaml | 17 + go.mod | 29 +- go.sum | 148 +- irc/accounts.go | 67 + irc/client.go | 8 +- irc/cloaks/cloaks.go | 40 + irc/config.go | 7 + irc/errors.go | 2 + irc/handlers.go | 51 +- irc/nickserv.go | 15 +- irc/nostr/dm.go | 319 + irc/nostr/errors.go | 37 + irc/nostr/nip05.go | 115 + irc/nostr/nostr.go | 160 + irc/nostr/relay.go | 271 + languages/example/help.lang.json | 4 +- languages/example/nickserv.lang.json | 20 +- vendor/github.com/ImVexed/fasturl/.gitignore | 2 + vendor/github.com/ImVexed/fasturl/LICENSE | 21 + vendor/github.com/ImVexed/fasturl/Makefile | 2 + vendor/github.com/ImVexed/fasturl/parser.go | 8867 +++++++++ vendor/github.com/ImVexed/fasturl/parser.rl | 122 + .../github.com/ImVexed/fasturl/parser_fuzz.go | 10 + vendor/github.com/ImVexed/fasturl/readme.md | 36 + .../github.com/btcsuite/btcd/btcec/v2/LICENSE | 16 + .../btcsuite/btcd/btcec/v2/README.md | 40 + .../btcsuite/btcd/btcec/v2/btcec.go | 56 + .../btcsuite/btcd/btcec/v2/ciphering.go | 16 + .../btcsuite/btcd/btcec/v2/curve.go | 115 + .../github.com/btcsuite/btcd/btcec/v2/doc.go | 21 + .../btcsuite/btcd/btcec/v2/error.go | 24 + .../btcsuite/btcd/btcec/v2/field.go | 43 + .../btcsuite/btcd/btcec/v2/modnscalar.go | 45 + .../btcsuite/btcd/btcec/v2/privkey.go | 37 + .../btcsuite/btcd/btcec/v2/pubkey.go | 88 + .../btcsuite/btcd/btcec/v2/schnorr/error.go | 25 + .../btcsuite/btcd/btcec/v2/schnorr/pubkey.go | 49 + .../btcd/btcec/v2/schnorr/signature.go | 538 + .../github.com/btcsuite/btcd/btcutil/LICENSE | 16 + .../btcsuite/btcd/btcutil/bech32/README.md | 29 + .../btcsuite/btcd/btcutil/bech32/bech32.go | 442 + .../btcsuite/btcd/btcutil/bech32/doc.go | 15 + .../btcsuite/btcd/btcutil/bech32/error.go | 87 + .../btcsuite/btcd/btcutil/bech32/version.go | 43 + .../btcsuite/btcd/chaincfg/chainhash/LICENSE | 16 + .../btcd/chaincfg/chainhash/README.md | 41 + .../btcsuite/btcd/chaincfg/chainhash/doc.go | 5 + .../btcsuite/btcd/chaincfg/chainhash/hash.go | 239 + .../btcd/chaincfg/chainhash/hashfuncs.go | 57 + vendor/github.com/bytedance/sonic/LICENSE | 201 + vendor/github.com/bytedance/sonic/ast/api.go | 135 + .../bytedance/sonic/ast/api_compat.go | 115 + vendor/github.com/bytedance/sonic/ast/asm.s | 0 .../github.com/bytedance/sonic/ast/buffer.go | 470 + .../github.com/bytedance/sonic/ast/decode.go | 562 + .../github.com/bytedance/sonic/ast/encode.go | 274 + .../github.com/bytedance/sonic/ast/error.go | 134 + .../bytedance/sonic/ast/iterator.go | 216 + vendor/github.com/bytedance/sonic/ast/node.go | 1843 ++ .../github.com/bytedance/sonic/ast/parser.go | 766 + .../github.com/bytedance/sonic/ast/search.go | 157 + .../github.com/bytedance/sonic/ast/stubs.go | 31 + .../github.com/bytedance/sonic/ast/visitor.go | 332 + .../bytedance/sonic/encoder/encoder_compat.go | 262 + .../bytedance/sonic/encoder/encoder_native.go | 120 + .../bytedance/sonic/internal/caching/asm.s | 0 .../sonic/internal/caching/fcache.go | 115 + .../sonic/internal/caching/hashing.go | 36 + .../sonic/internal/caching/pcache.go | 173 + .../bytedance/sonic/internal/compat/warn.go | 12 + .../bytedance/sonic/internal/cpu/features.go | 40 + .../sonic/internal/encoder/alg/mapiter.go | 207 + .../sonic/internal/encoder/alg/opts.go | 31 + .../sonic/internal/encoder/alg/primitives.go | 104 + .../sonic/internal/encoder/alg/sort.go | 206 + .../sonic/internal/encoder/alg/spec.go | 198 + .../sonic/internal/encoder/alg/spec_compat.go | 148 + .../sonic/internal/encoder/compiler.go | 687 + .../sonic/internal/encoder/encode_norace.go | 24 + .../sonic/internal/encoder/encode_race.go | 54 + .../sonic/internal/encoder/encoder.go | 318 + .../bytedance/sonic/internal/encoder/ir/op.go | 501 + .../sonic/internal/encoder/pools_amd64.go | 78 + .../sonic/internal/encoder/pools_compt.go | 24 + .../sonic/internal/encoder/stream.go | 91 + .../sonic/internal/encoder/vars/cache.go | 48 + .../sonic/internal/encoder/vars/const.go | 42 + .../sonic/internal/encoder/vars/errors.go | 69 + .../sonic/internal/encoder/vars/stack.go | 146 + .../sonic/internal/encoder/vars/types.go | 47 + .../sonic/internal/encoder/vm/stbus.go | 45 + .../bytedance/sonic/internal/encoder/vm/vm.go | 374 + .../encoder/x86/asm_stubs_amd64_go117.go | 53 + .../encoder/x86/asm_stubs_amd64_go121.go | 52 + .../encoder/x86/assembler_regabi_amd64.go | 1220 ++ .../sonic/internal/encoder/x86/debug_go116.go | 66 + .../sonic/internal/encoder/x86/debug_go117.go | 201 + .../sonic/internal/encoder/x86/stbus.go | 51 + .../sonic/internal/jit/arch_amd64.go | 76 + .../bytedance/sonic/internal/jit/asm.s | 0 .../sonic/internal/jit/assembler_amd64.go | 269 + .../bytedance/sonic/internal/jit/backend.go | 117 + .../bytedance/sonic/internal/jit/runtime.go | 49 + .../sonic/internal/native/avx2/f32toa.go | 35 + .../sonic/internal/native/avx2/f32toa_subr.go | 46 + .../internal/native/avx2/f32toa_text_amd64.go | 1066 ++ .../sonic/internal/native/avx2/f64toa.go | 35 + .../sonic/internal/native/avx2/f64toa_subr.go | 46 + .../internal/native/avx2/f64toa_text_amd64.go | 2504 +++ .../sonic/internal/native/avx2/get_by_path.go | 35 + .../internal/native/avx2/get_by_path_subr.go | 46 + .../native/avx2/get_by_path_text_amd64.go | 6340 +++++++ .../sonic/internal/native/avx2/html_escape.go | 34 + .../internal/native/avx2/html_escape_subr.go | 45 + .../native/avx2/html_escape_text_amd64.go | 832 + .../sonic/internal/native/avx2/i64toa.go | 35 + .../sonic/internal/native/avx2/i64toa_subr.go | 47 + .../internal/native/avx2/i64toa_text_amd64.go | 631 + .../internal/native/avx2/lookup_small_key.go | 37 + .../native/avx2/lookup_small_key_subr.go | 46 + .../avx2/lookup_small_key_text_amd64.go | 221 + .../sonic/internal/native/avx2/lspace.go | 35 + .../sonic/internal/native/avx2/lspace_subr.go | 38 + .../internal/native/avx2/lspace_text_amd64.go | 112 + .../internal/native/avx2/native_export.go | 51 + .../native/avx2/parse_with_padding.go | 36 + .../native/avx2/parse_with_padding_subr.go | 46 + .../avx2/parse_with_padding_text_amd64.go | 15233 ++++++++++++++++ .../sonic/internal/native/avx2/quote.go | 33 + .../sonic/internal/native/avx2/quote_subr.go | 46 + .../internal/native/avx2/quote_text_amd64.go | 1390 ++ .../sonic/internal/native/avx2/skip_array.go | 35 + .../internal/native/avx2/skip_array_subr.go | 46 + .../native/avx2/skip_array_text_amd64.go | 4198 +++++ .../sonic/internal/native/avx2/skip_number.go | 34 + .../internal/native/avx2/skip_number_subr.go | 46 + .../native/avx2/skip_number_text_amd64.go | 494 + .../sonic/internal/native/avx2/skip_object.go | 35 + .../internal/native/avx2/skip_object_subr.go | 46 + .../native/avx2/skip_object_text_amd64.go | 4198 +++++ .../sonic/internal/native/avx2/skip_one.go | 35 + .../internal/native/avx2/skip_one_fast.go | 35 + .../native/avx2/skip_one_fast_subr.go | 46 + .../native/avx2/skip_one_fast_text_amd64.go | 956 + .../internal/native/avx2/skip_one_subr.go | 46 + .../native/avx2/skip_one_text_amd64.go | 3957 ++++ .../sonic/internal/native/avx2/u64toa.go | 34 + .../sonic/internal/native/avx2/u64toa_subr.go | 39 + .../internal/native/avx2/u64toa_text_amd64.go | 364 + .../sonic/internal/native/avx2/unquote.go | 34 + .../internal/native/avx2/unquote_subr.go | 46 + .../native/avx2/unquote_text_amd64.go | 622 + .../internal/native/avx2/validate_one.go | 35 + .../internal/native/avx2/validate_one_subr.go | 46 + .../native/avx2/validate_one_text_amd64.go | 4200 +++++ .../internal/native/avx2/validate_utf8.go | 37 + .../native/avx2/validate_utf8_fast.go | 34 + .../native/avx2/validate_utf8_fast_subr.go | 42 + .../avx2/validate_utf8_fast_text_amd64.go | 753 + .../native/avx2/validate_utf8_subr.go | 44 + .../native/avx2/validate_utf8_text_amd64.go | 193 + .../sonic/internal/native/avx2/value.go | 33 + .../sonic/internal/native/avx2/value_subr.go | 46 + .../internal/native/avx2/value_text_amd64.go | 5554 ++++++ .../sonic/internal/native/avx2/vnumber.go | 33 + .../internal/native/avx2/vnumber_subr.go | 45 + .../native/avx2/vnumber_text_amd64.go | 4216 +++++ .../sonic/internal/native/avx2/vsigned.go | 33 + .../internal/native/avx2/vsigned_subr.go | 50 + .../native/avx2/vsigned_text_amd64.go | 120 + .../sonic/internal/native/avx2/vstring.go | 33 + .../internal/native/avx2/vstring_subr.go | 46 + .../native/avx2/vstring_text_amd64.go | 513 + .../sonic/internal/native/avx2/vunsigned.go | 33 + .../internal/native/avx2/vunsigned_subr.go | 57 + .../native/avx2/vunsigned_text_amd64.go | 127 + .../sonic/internal/native/dispatch_amd64.go | 258 + .../sonic/internal/native/dispatch_arm64.go | 169 + .../sonic/internal/native/f32toa.tmpl | 35 + .../sonic/internal/native/f64toa.tmpl | 35 + .../sonic/internal/native/fastfloat_test.tmpl | 143 + .../sonic/internal/native/fastint_test.tmpl | 156 + .../sonic/internal/native/get_by_path.tmpl | 35 + .../sonic/internal/native/html_escape.tmpl | 34 + .../sonic/internal/native/i64toa.tmpl | 35 + .../internal/native/lookup_small_key.tmpl | 37 + .../sonic/internal/native/lspace.tmpl | 35 + .../sonic/internal/native/native_export.tmpl | 51 + .../sonic/internal/native/native_test.tmpl | 636 + .../internal/native/neon/f32toa_arm64.go | 29 + .../sonic/internal/native/neon/f32toa_arm64.s | 1019 ++ .../internal/native/neon/f32toa_subr_arm64.go | 25 + .../internal/native/neon/f64toa_arm64.go | 29 + .../sonic/internal/native/neon/f64toa_arm64.s | 2492 +++ .../internal/native/neon/f64toa_subr_arm64.go | 25 + .../internal/native/neon/get_by_path_arm64.go | 33 + .../internal/native/neon/get_by_path_arm64.s | 5427 ++++++ .../native/neon/get_by_path_subr_arm64.go | 25 + .../internal/native/neon/html_escape_arm64.go | 35 + .../internal/native/neon/html_escape_arm64.s | 1406 ++ .../native/neon/html_escape_subr_arm64.go | 25 + .../internal/native/neon/i64toa_arm64.go | 29 + .../sonic/internal/native/neon/i64toa_arm64.s | 985 + .../internal/native/neon/i64toa_subr_arm64.go | 25 + .../native/neon/lookup_small_key_arm64.go | 31 + .../native/neon/lookup_small_key_arm64.s | 342 + .../neon/lookup_small_key_subr_arm64.go | 25 + .../internal/native/neon/lspace_arm64.go | 35 + .../sonic/internal/native/neon/lspace_arm64.s | 68 + .../internal/native/neon/lspace_subr_arm64.go | 25 + .../native/neon/native_export_arm64.go | 51 + .../native/neon/parse_with_padding_arm64.go | 30 + .../native/neon/parse_with_padding_arm64.s | 14113 ++++++++++++++ .../neon/parse_with_padding_subr_arm64.go | 25 + .../sonic/internal/native/neon/quote_arm64.go | 35 + .../sonic/internal/native/neon/quote_arm64.s | 2563 +++ .../internal/native/neon/quote_subr_arm64.go | 25 + .../internal/native/neon/skip_array_arm64.go | 35 + .../internal/native/neon/skip_array_arm64.s | 3496 ++++ .../native/neon/skip_array_subr_arm64.go | 25 + .../internal/native/neon/skip_number_arm64.go | 29 + .../internal/native/neon/skip_number_arm64.s | 373 + .../native/neon/skip_number_subr_arm64.go | 25 + .../internal/native/neon/skip_object_arm64.go | 35 + .../internal/native/neon/skip_object_arm64.s | 3496 ++++ .../native/neon/skip_object_subr_arm64.go | 25 + .../internal/native/neon/skip_one_arm64.go | 35 + .../internal/native/neon/skip_one_arm64.s | 3255 ++++ .../native/neon/skip_one_fast_arm64.go | 29 + .../native/neon/skip_one_fast_arm64.s | 998 + .../native/neon/skip_one_fast_subr_arm64.go | 25 + .../native/neon/skip_one_subr_arm64.go | 25 + .../internal/native/neon/u64toa_arm64.go | 29 + .../sonic/internal/native/neon/u64toa_arm64.s | 598 + .../internal/native/neon/u64toa_subr_arm64.go | 25 + .../internal/native/neon/unquote_arm64.go | 35 + .../internal/native/neon/unquote_arm64.s | 617 + .../native/neon/unquote_subr_arm64.go | 25 + .../native/neon/validate_one_arm64.go | 35 + .../internal/native/neon/validate_one_arm64.s | 3495 ++++ .../native/neon/validate_one_subr_arm64.go | 25 + .../native/neon/validate_utf8_arm64.go | 36 + .../native/neon/validate_utf8_arm64.s | 222 + .../native/neon/validate_utf8_fast_arm64.go | 29 + .../native/neon/validate_utf8_fast_arm64.s | 182 + .../neon/validate_utf8_fast_subr_arm64.go | 25 + .../native/neon/validate_utf8_subr_arm64.go | 25 + .../sonic/internal/native/neon/value_arm64.go | 34 + .../sonic/internal/native/neon/value_arm64.s | 5968 ++++++ .../internal/native/neon/value_subr_arm64.go | 25 + .../internal/native/neon/vnumber_arm64.go | 34 + .../internal/native/neon/vnumber_arm64.s | 4690 +++++ .../native/neon/vnumber_subr_arm64.go | 25 + .../internal/native/neon/vsigned_arm64.go | 32 + .../internal/native/neon/vsigned_arm64.s | 156 + .../native/neon/vsigned_subr_arm64.go | 25 + .../internal/native/neon/vstring_arm64.go | 32 + .../internal/native/neon/vstring_arm64.s | 628 + .../native/neon/vstring_subr_arm64.go | 25 + .../internal/native/neon/vunsigned_arm64.go | 32 + .../internal/native/neon/vunsigned_arm64.s | 150 + .../native/neon/vunsigned_subr_arm64.go | 25 + .../internal/native/parse_with_padding.tmpl | 36 + .../sonic/internal/native/quote.tmpl | 33 + .../sonic/internal/native/recover_test.tmpl | 722 + .../sonic/internal/native/skip_array.tmpl | 35 + .../sonic/internal/native/skip_number.tmpl | 34 + .../sonic/internal/native/skip_object.tmpl | 35 + .../sonic/internal/native/skip_one.tmpl | 35 + .../sonic/internal/native/skip_one_fast.tmpl | 35 + .../sonic/internal/native/sse/f32toa.go | 35 + .../sonic/internal/native/sse/f32toa_subr.go | 46 + .../internal/native/sse/f32toa_text_amd64.go | 1055 ++ .../sonic/internal/native/sse/f64toa.go | 35 + .../sonic/internal/native/sse/f64toa_subr.go | 46 + .../internal/native/sse/f64toa_text_amd64.go | 2493 +++ .../sonic/internal/native/sse/get_by_path.go | 35 + .../internal/native/sse/get_by_path_subr.go | 46 + .../native/sse/get_by_path_text_amd64.go | 6217 +++++++ .../sonic/internal/native/sse/html_escape.go | 34 + .../internal/native/sse/html_escape_subr.go | 45 + .../native/sse/html_escape_text_amd64.go | 634 + .../sonic/internal/native/sse/i64toa.go | 35 + .../sonic/internal/native/sse/i64toa_subr.go | 47 + .../internal/native/sse/i64toa_text_amd64.go | 658 + .../internal/native/sse/lookup_small_key.go | 37 + .../native/sse/lookup_small_key_subr.go | 46 + .../native/sse/lookup_small_key_text_amd64.go | 245 + .../sonic/internal/native/sse/lspace.go | 35 + .../sonic/internal/native/sse/lspace_subr.go | 33 + .../internal/native/sse/lspace_text_amd64.go | 37 + .../internal/native/sse/native_export.go | 51 + .../internal/native/sse/parse_with_padding.go | 36 + .../native/sse/parse_with_padding_subr.go | 46 + .../sse/parse_with_padding_text_amd64.go | 14922 +++++++++++++++ .../sonic/internal/native/sse/quote.go | 33 + .../sonic/internal/native/sse/quote_subr.go | 46 + .../internal/native/sse/quote_text_amd64.go | 1111 ++ .../sonic/internal/native/sse/skip_array.go | 35 + .../internal/native/sse/skip_array_subr.go | 46 + .../native/sse/skip_array_text_amd64.go | 4175 +++++ .../sonic/internal/native/sse/skip_number.go | 34 + .../internal/native/sse/skip_number_subr.go | 46 + .../native/sse/skip_number_text_amd64.go | 351 + .../sonic/internal/native/sse/skip_object.go | 35 + .../internal/native/sse/skip_object_subr.go | 46 + .../native/sse/skip_object_text_amd64.go | 4175 +++++ .../sonic/internal/native/sse/skip_one.go | 35 + .../internal/native/sse/skip_one_fast.go | 35 + .../internal/native/sse/skip_one_fast_subr.go | 46 + .../native/sse/skip_one_fast_text_amd64.go | 1038 ++ .../internal/native/sse/skip_one_subr.go | 46 + .../native/sse/skip_one_text_amd64.go | 3989 ++++ .../sonic/internal/native/sse/u64toa.go | 34 + .../sonic/internal/native/sse/u64toa_subr.go | 39 + .../internal/native/sse/u64toa_text_amd64.go | 384 + .../sonic/internal/native/sse/unquote.go | 34 + .../sonic/internal/native/sse/unquote_subr.go | 46 + .../internal/native/sse/unquote_text_amd64.go | 571 + .../sonic/internal/native/sse/validate_one.go | 35 + .../internal/native/sse/validate_one_subr.go | 46 + .../native/sse/validate_one_text_amd64.go | 4177 +++++ .../internal/native/sse/validate_utf8.go | 37 + .../internal/native/sse/validate_utf8_fast.go | 34 + .../native/sse/validate_utf8_fast_subr.go | 41 + .../sse/validate_utf8_fast_text_amd64.go | 158 + .../internal/native/sse/validate_utf8_subr.go | 44 + .../native/sse/validate_utf8_text_amd64.go | 193 + .../sonic/internal/native/sse/value.go | 33 + .../sonic/internal/native/sse/value_subr.go | 46 + .../internal/native/sse/value_text_amd64.go | 5312 ++++++ .../sonic/internal/native/sse/vnumber.go | 33 + .../sonic/internal/native/sse/vnumber_subr.go | 45 + .../internal/native/sse/vnumber_text_amd64.go | 4083 +++++ .../sonic/internal/native/sse/vsigned.go | 33 + .../sonic/internal/native/sse/vsigned_subr.go | 50 + .../internal/native/sse/vsigned_text_amd64.go | 120 + .../sonic/internal/native/sse/vstring.go | 33 + .../sonic/internal/native/sse/vstring_subr.go | 46 + .../internal/native/sse/vstring_text_amd64.go | 657 + .../sonic/internal/native/sse/vunsigned.go | 33 + .../internal/native/sse/vunsigned_subr.go | 57 + .../native/sse/vunsigned_text_amd64.go | 127 + .../internal/native/traceback_test.mock_tmpl | 379 + .../sonic/internal/native/types/types.go | 167 + .../sonic/internal/native/u64toa.tmpl | 34 + .../sonic/internal/native/unquote.tmpl | 34 + .../sonic/internal/native/validate_one.tmpl | 35 + .../sonic/internal/native/validate_utf8.tmpl | 37 + .../internal/native/validate_utf8_fast.tmpl | 34 + .../sonic/internal/native/value.tmpl | 33 + .../sonic/internal/native/vnumber.tmpl | 33 + .../sonic/internal/native/vsigned.tmpl | 33 + .../sonic/internal/native/vstring.tmpl | 33 + .../sonic/internal/native/vunsigned.tmpl | 33 + .../bytedance/sonic/internal/resolver/asm.s | 0 .../sonic/internal/resolver/resolver.go | 218 + .../sonic/internal/resolver/stubs_go120.go | 51 + .../sonic/internal/resolver/stubs_go123.go | 51 + .../sonic/internal/resolver/stubs_latest.go | 59 + .../bytedance/sonic/internal/rt/asm_amd64.s | 20 + .../bytedance/sonic/internal/rt/asm_compat.s | 10 + .../bytedance/sonic/internal/rt/assertI2I.go | 42 + .../sonic/internal/rt/base64_amd64.go | 44 + .../sonic/internal/rt/base64_compat.go | 37 + .../bytedance/sonic/internal/rt/fastconv.go | 175 + .../bytedance/sonic/internal/rt/fastmem.go | 155 + .../bytedance/sonic/internal/rt/fastvalue.go | 231 + .../bytedance/sonic/internal/rt/gcwb.go | 85 + .../sonic/internal/rt/gcwb_legacy.go | 29 + .../bytedance/sonic/internal/rt/growslice.go | 36 + .../sonic/internal/rt/growslice_legacy.go | 27 + .../bytedance/sonic/internal/rt/int48.go | 36 + .../bytedance/sonic/internal/rt/map_legacy.go | 25 + .../sonic/internal/rt/map_nosiwss_go124.go | 28 + .../sonic/internal/rt/map_siwss_go124.go | 15 + .../bytedance/sonic/internal/rt/pool.go | 31 + .../bytedance/sonic/internal/rt/stubs.go | 200 + .../bytedance/sonic/internal/rt/table.go | 118 + .../bytedance/sonic/internal/rt/types.go | 45 + .../bytedance/sonic/internal/utils/skip.go | 79 + .../github.com/bytedance/sonic/loader/LICENSE | 201 + .../bytedance/sonic/loader/funcdata.go | 245 + .../bytedance/sonic/loader/funcdata_compat.go | 460 + .../bytedance/sonic/loader/funcdata_go117.go | 461 + .../bytedance/sonic/loader/funcdata_go118.go | 113 + .../bytedance/sonic/loader/funcdata_go120.go | 114 + .../bytedance/sonic/loader/funcdata_go121.go | 119 + .../bytedance/sonic/loader/funcdata_go123.go | 118 + .../bytedance/sonic/loader/funcdata_latest.go | 355 + .../sonic/loader/internal/abi/abi.go | 197 + .../sonic/loader/internal/abi/abi_amd64.go | 301 + .../loader/internal/abi/abi_legacy_amd64.go | 215 + .../loader/internal/abi/abi_regabi_amd64.go | 345 + .../sonic/loader/internal/abi/stubs.go | 35 + .../sonic/loader/internal/iasm/expr/ast.go | 273 + .../sonic/loader/internal/iasm/expr/errors.go | 53 + .../sonic/loader/internal/iasm/expr/ops.go | 67 + .../sonic/loader/internal/iasm/expr/parser.go | 331 + .../sonic/loader/internal/iasm/expr/pools.go | 42 + .../sonic/loader/internal/iasm/expr/term.go | 23 + .../sonic/loader/internal/iasm/expr/utils.go | 77 + .../sonic/loader/internal/iasm/x86_64/arch.go | 251 + .../sonic/loader/internal/iasm/x86_64/asm.s | 16 + .../loader/internal/iasm/x86_64/eface.go | 79 + .../loader/internal/iasm/x86_64/encodings.go | 836 + .../internal/iasm/x86_64/instructions.go | 1077 ++ .../iasm/x86_64/instructions_table.go | 24 + .../loader/internal/iasm/x86_64/operands.go | 665 + .../loader/internal/iasm/x86_64/pools.go | 54 + .../loader/internal/iasm/x86_64/program.go | 584 + .../loader/internal/iasm/x86_64/registers.go | 747 + .../loader/internal/iasm/x86_64/utils.go | 147 + .../sonic/loader/internal/rt/fastmem.go | 62 + .../sonic/loader/internal/rt/fastvalue.go | 183 + .../sonic/loader/internal/rt/stackmap.go | 228 + .../bytedance/sonic/loader/loader.go | 37 + .../bytedance/sonic/loader/loader_latest.go | 111 + .../bytedance/sonic/loader/mmap_unix.go | 45 + .../bytedance/sonic/loader/mmap_windows.go | 84 + .../bytedance/sonic/loader/pcdata.go | 93 + .../bytedance/sonic/loader/register.go | 55 + .../bytedance/sonic/loader/register_tango.go | 34 + .../bytedance/sonic/loader/stubs.go | 28 + .../bytedance/sonic/loader/wrapper.go | 185 + .../bytedance/sonic/option/option.go | 92 + .../bytedance/sonic/unquote/unquote.go | 80 + .../github.com/bytedance/sonic/utf8/utf8.go | 81 + .../github.com/cloudwego/base64x/.gitignore | 30 + .../github.com/cloudwego/base64x/.gitmodules | 3 + .../cloudwego/base64x/.golangci.yaml | 37 + .../cloudwego/base64x/.licenserc.yaml | 14 + .../cloudwego/base64x/CODE_OF_CONDUCT.md | 128 + .../cloudwego/base64x/CONTRIBUTING.md | 55 + vendor/github.com/cloudwego/base64x/LICENSE | 201 + .../cloudwego/base64x/LICENSE-APACHE | 177 + vendor/github.com/cloudwego/base64x/Makefile | 29 + vendor/github.com/cloudwego/base64x/README.md | 4 + .../github.com/cloudwego/base64x/_typos.toml | 4 + .../github.com/cloudwego/base64x/base64x.go | 169 + .../cloudwego/base64x/base64x_subr_amd64.go | 18 + .../cloudwego/base64x/check_branch_name.sh | 10 + .../github.com/cloudwego/base64x/faststr.go | 51 + .../base64x/internal/native/avx2/b64decode.go | 35 + .../internal/native/avx2/b64decode_subr.go | 45 + .../native/avx2/b64decode_text_amd64.go | 3981 ++++ .../base64x/internal/native/avx2/b64encode.go | 34 + .../internal/native/avx2/b64encode_subr.go | 41 + .../native/avx2/b64encode_text_amd64.go | 387 + .../internal/native/avx2/native_export.go | 29 + .../base64x/internal/native/b64decode.tmpl | 35 + .../base64x/internal/native/b64encode.tmpl | 34 + .../base64x/internal/native/dispatch.go | 63 + .../internal/native/native_export.tmpl | 29 + .../base64x/internal/native/sse/b64decode.go | 35 + .../internal/native/sse/b64decode_subr.go | 45 + .../native/sse/b64decode_text_amd64.go | 2791 +++ .../base64x/internal/native/sse/b64encode.go | 34 + .../internal/native/sse/b64encode_subr.go | 39 + .../native/sse/b64encode_text_amd64.go | 148 + .../internal/native/sse/native_export.go | 29 + .../cloudwego/base64x/internal/rt/asm_amd64.s | 20 + .../cloudwego/base64x/internal/rt/asm_arm64.s | 10 + .../cloudwego/base64x/internal/rt/fastmem.go | 42 + vendor/github.com/coder/websocket/LICENSE.txt | 13 + vendor/github.com/coder/websocket/README.md | 160 + vendor/github.com/coder/websocket/accept.go | 352 + vendor/github.com/coder/websocket/close.go | 348 + vendor/github.com/coder/websocket/compress.go | 233 + vendor/github.com/coder/websocket/conn.go | 295 + vendor/github.com/coder/websocket/dial.go | 330 + vendor/github.com/coder/websocket/doc.go | 34 + vendor/github.com/coder/websocket/frame.go | 173 + .../coder/websocket/internal/bpool/bpool.go | 24 + .../coder/websocket/internal/errd/wrap.go | 14 + .../coder/websocket/internal/util/util.go | 15 + .../coder/websocket/internal/wsjs/wsjs_js.go | 169 + .../coder/websocket/internal/xsync/go.go | 26 + .../coder/websocket/internal/xsync/int64.go | 23 + vendor/github.com/coder/websocket/make.sh | 12 + vendor/github.com/coder/websocket/mask.go | 128 + .../github.com/coder/websocket/mask_amd64.s | 127 + .../github.com/coder/websocket/mask_arm64.s | 72 + vendor/github.com/coder/websocket/mask_asm.go | 26 + vendor/github.com/coder/websocket/mask_go.go | 7 + vendor/github.com/coder/websocket/netconn.go | 237 + .../github.com/coder/websocket/netconn_js.go | 11 + .../coder/websocket/netconn_notjs.go | 20 + vendor/github.com/coder/websocket/read.go | 506 + vendor/github.com/coder/websocket/stringer.go | 91 + vendor/github.com/coder/websocket/write.go | 376 + vendor/github.com/coder/websocket/ws_js.go | 598 + .../decred/dcrd/crypto/blake256/LICENSE | 17 + .../decred/dcrd/crypto/blake256/README.md | 190 + .../decred/dcrd/crypto/blake256/error.go | 50 + .../decred/dcrd/crypto/blake256/hasher.go | 415 + .../decred/dcrd/crypto/blake256/hasher224.go | 278 + .../decred/dcrd/crypto/blake256/hasher256.go | 278 + .../blake256/internal/compress/README.md | 55 + .../internal/compress/blocks_amd64.go | 26 + .../blake256/internal/compress/blocks_amd64.s | 4072 +++++ .../internal/compress/blocks_generic.go | 312 + .../internal/compress/blocks_noasm.go | 25 + .../internal/compress/blocksisa_amd64.go | 35 + .../blake256/internal/compress/cpu_amd64.go | 182 + .../blake256/internal/compress/cpu_amd64.s | 62 + .../decred/dcrd/dcrec/secp256k1/v4/LICENSE | 17 + .../decred/dcrd/dcrec/secp256k1/v4/README.md | 72 + .../secp256k1/v4/compressedbytepoints.go | 18 + .../decred/dcrd/dcrec/secp256k1/v4/curve.go | 1310 ++ .../dcrd/dcrec/secp256k1/v4/curve_embedded.go | 14 + .../dcrec/secp256k1/v4/curve_precompute.go | 14 + .../decred/dcrd/dcrec/secp256k1/v4/doc.go | 59 + .../decred/dcrd/dcrec/secp256k1/v4/ecdh.go | 21 + .../dcrec/secp256k1/v4/ellipticadaptor.go | 255 + .../decred/dcrd/dcrec/secp256k1/v4/error.go | 67 + .../decred/dcrd/dcrec/secp256k1/v4/field.go | 1696 ++ .../dcrec/secp256k1/v4/loadprecomputed.go | 91 + .../dcrd/dcrec/secp256k1/v4/modnscalar.go | 1105 ++ .../decred/dcrd/dcrec/secp256k1/v4/nonce.go | 263 + .../decred/dcrd/dcrec/secp256k1/v4/privkey.go | 111 + .../decred/dcrd/dcrec/secp256k1/v4/pubkey.go | 236 + .../dcrd/dcrec/secp256k1/v4/schnorr/README.md | 334 + .../dcrd/dcrec/secp256k1/v4/schnorr/doc.go | 102 + .../dcrd/dcrec/secp256k1/v4/schnorr/error.go | 85 + .../dcrd/dcrec/secp256k1/v4/schnorr/pubkey.go | 45 + .../dcrec/secp256k1/v4/schnorr/signature.go | 404 + vendor/github.com/josharian/intern/README.md | 5 + vendor/github.com/josharian/intern/intern.go | 44 + vendor/github.com/josharian/intern/license.md | 21 + .../github.com/json-iterator/go/.codecov.yml | 3 + vendor/github.com/json-iterator/go/.gitignore | 4 + .../github.com/json-iterator/go/.travis.yml | 14 + vendor/github.com/json-iterator/go/Gopkg.lock | 21 + vendor/github.com/json-iterator/go/Gopkg.toml | 26 + vendor/github.com/json-iterator/go/LICENSE | 21 + vendor/github.com/json-iterator/go/README.md | 85 + vendor/github.com/json-iterator/go/adapter.go | 150 + vendor/github.com/json-iterator/go/any.go | 325 + .../github.com/json-iterator/go/any_array.go | 278 + .../github.com/json-iterator/go/any_bool.go | 137 + .../github.com/json-iterator/go/any_float.go | 83 + .../github.com/json-iterator/go/any_int32.go | 74 + .../github.com/json-iterator/go/any_int64.go | 74 + .../json-iterator/go/any_invalid.go | 82 + vendor/github.com/json-iterator/go/any_nil.go | 69 + .../github.com/json-iterator/go/any_number.go | 123 + .../github.com/json-iterator/go/any_object.go | 374 + vendor/github.com/json-iterator/go/any_str.go | 166 + .../github.com/json-iterator/go/any_uint32.go | 74 + .../github.com/json-iterator/go/any_uint64.go | 74 + vendor/github.com/json-iterator/go/build.sh | 12 + vendor/github.com/json-iterator/go/config.go | 375 + .../go/fuzzy_mode_convert_table.md | 7 + vendor/github.com/json-iterator/go/iter.go | 349 + .../github.com/json-iterator/go/iter_array.go | 64 + .../github.com/json-iterator/go/iter_float.go | 342 + .../github.com/json-iterator/go/iter_int.go | 346 + .../json-iterator/go/iter_object.go | 267 + .../github.com/json-iterator/go/iter_skip.go | 130 + .../json-iterator/go/iter_skip_sloppy.go | 163 + .../json-iterator/go/iter_skip_strict.go | 99 + .../github.com/json-iterator/go/iter_str.go | 215 + .../github.com/json-iterator/go/jsoniter.go | 18 + vendor/github.com/json-iterator/go/pool.go | 42 + vendor/github.com/json-iterator/go/reflect.go | 337 + .../json-iterator/go/reflect_array.go | 104 + .../json-iterator/go/reflect_dynamic.go | 70 + .../json-iterator/go/reflect_extension.go | 483 + .../json-iterator/go/reflect_json_number.go | 112 + .../go/reflect_json_raw_message.go | 76 + .../json-iterator/go/reflect_map.go | 346 + .../json-iterator/go/reflect_marshaler.go | 225 + .../json-iterator/go/reflect_native.go | 453 + .../json-iterator/go/reflect_optional.go | 129 + .../json-iterator/go/reflect_slice.go | 99 + .../go/reflect_struct_decoder.go | 1097 ++ .../go/reflect_struct_encoder.go | 211 + vendor/github.com/json-iterator/go/stream.go | 210 + .../json-iterator/go/stream_float.go | 111 + .../github.com/json-iterator/go/stream_int.go | 190 + .../github.com/json-iterator/go/stream_str.go | 372 + vendor/github.com/json-iterator/go/test.sh | 12 + .../github.com/klauspost/cpuid/v2/.gitignore | 24 + .../klauspost/cpuid/v2/.goreleaser.yml | 57 + .../klauspost/cpuid/v2/CONTRIBUTING.txt | 35 + vendor/github.com/klauspost/cpuid/v2/LICENSE | 22 + .../github.com/klauspost/cpuid/v2/README.md | 505 + vendor/github.com/klauspost/cpuid/v2/cpuid.go | 1566 ++ .../github.com/klauspost/cpuid/v2/cpuid_386.s | 47 + .../klauspost/cpuid/v2/cpuid_amd64.s | 72 + .../klauspost/cpuid/v2/cpuid_arm64.s | 36 + .../klauspost/cpuid/v2/detect_arm64.go | 250 + .../klauspost/cpuid/v2/detect_ref.go | 17 + .../klauspost/cpuid/v2/detect_x86.go | 41 + .../klauspost/cpuid/v2/featureid_string.go | 297 + .../klauspost/cpuid/v2/os_darwin_arm64.go | 127 + .../klauspost/cpuid/v2/os_linux_arm64.go | 208 + .../klauspost/cpuid/v2/os_other_arm64.go | 16 + .../klauspost/cpuid/v2/os_safe_linux_arm64.go | 8 + .../cpuid/v2/os_unsafe_linux_arm64.go | 11 + .../klauspost/cpuid/v2/test-architectures.sh | 15 + vendor/github.com/mailru/easyjson/.gitignore | 6 + vendor/github.com/mailru/easyjson/LICENSE | 7 + vendor/github.com/mailru/easyjson/Makefile | 72 + vendor/github.com/mailru/easyjson/README.md | 408 + .../github.com/mailru/easyjson/buffer/pool.go | 278 + vendor/github.com/mailru/easyjson/helpers.go | 114 + .../mailru/easyjson/jlexer/bytestostr.go | 21 + .../easyjson/jlexer/bytestostr_nounsafe.go | 13 + .../mailru/easyjson/jlexer/error.go | 15 + .../mailru/easyjson/jlexer/lexer.go | 1257 ++ .../mailru/easyjson/jwriter/writer.go | 417 + vendor/github.com/mailru/easyjson/raw.go | 46 + .../mailru/easyjson/unknown_fields.go | 32 + .../modern-go/concurrent/.gitignore | 1 + .../modern-go/concurrent/.travis.yml | 14 + .../github.com/modern-go/concurrent/LICENSE | 201 + .../github.com/modern-go/concurrent/README.md | 49 + .../modern-go/concurrent/executor.go | 14 + .../modern-go/concurrent/go_above_19.go | 15 + .../modern-go/concurrent/go_below_19.go | 33 + vendor/github.com/modern-go/concurrent/log.go | 13 + .../github.com/modern-go/concurrent/test.sh | 12 + .../concurrent/unbounded_executor.go | 119 + .../github.com/modern-go/reflect2/.gitignore | 2 + .../github.com/modern-go/reflect2/.travis.yml | 15 + .../github.com/modern-go/reflect2/Gopkg.lock | 9 + .../github.com/modern-go/reflect2/Gopkg.toml | 31 + vendor/github.com/modern-go/reflect2/LICENSE | 201 + .../github.com/modern-go/reflect2/README.md | 71 + .../modern-go/reflect2/go_above_118.go | 23 + .../modern-go/reflect2/go_above_19.go | 17 + .../modern-go/reflect2/go_below_118.go | 21 + .../github.com/modern-go/reflect2/reflect2.go | 300 + .../modern-go/reflect2/reflect2_amd64.s | 0 .../modern-go/reflect2/reflect2_kind.go | 30 + .../modern-go/reflect2/relfect2_386.s | 0 .../modern-go/reflect2/relfect2_amd64p32.s | 0 .../modern-go/reflect2/relfect2_arm.s | 0 .../modern-go/reflect2/relfect2_arm64.s | 0 .../modern-go/reflect2/relfect2_mips64x.s | 0 .../modern-go/reflect2/relfect2_mipsx.s | 0 .../modern-go/reflect2/relfect2_ppc64x.s | 0 .../modern-go/reflect2/relfect2_s390x.s | 0 .../modern-go/reflect2/safe_field.go | 58 + .../github.com/modern-go/reflect2/safe_map.go | 101 + .../modern-go/reflect2/safe_slice.go | 92 + .../modern-go/reflect2/safe_struct.go | 29 + .../modern-go/reflect2/safe_type.go | 78 + .../github.com/modern-go/reflect2/type_map.go | 70 + .../modern-go/reflect2/unsafe_array.go | 65 + .../modern-go/reflect2/unsafe_eface.go | 59 + .../modern-go/reflect2/unsafe_field.go | 74 + .../modern-go/reflect2/unsafe_iface.go | 64 + .../modern-go/reflect2/unsafe_link.go | 76 + .../modern-go/reflect2/unsafe_map.go | 130 + .../modern-go/reflect2/unsafe_ptr.go | 46 + .../modern-go/reflect2/unsafe_slice.go | 177 + .../modern-go/reflect2/unsafe_struct.go | 59 + .../modern-go/reflect2/unsafe_type.go | 85 + vendor/github.com/nbd-wtf/go-nostr/.gitignore | 2 + vendor/github.com/nbd-wtf/go-nostr/LICENSE.md | 21 + vendor/github.com/nbd-wtf/go-nostr/README.md | 164 + .../github.com/nbd-wtf/go-nostr/connection.go | 65 + .../nbd-wtf/go-nostr/connection_options.go | 34 + .../nbd-wtf/go-nostr/connection_options_js.go | 15 + .../github.com/nbd-wtf/go-nostr/envelopes.go | 437 + .../nbd-wtf/go-nostr/envelopes_default.go | 58 + .../nbd-wtf/go-nostr/envelopes_sonic.go | 564 + vendor/github.com/nbd-wtf/go-nostr/event.go | 102 + .../nbd-wtf/go-nostr/event_easyjson.go | 181 + vendor/github.com/nbd-wtf/go-nostr/filter.go | 215 + .../nbd-wtf/go-nostr/filter_easyjson.go | 309 + vendor/github.com/nbd-wtf/go-nostr/helpers.go | 217 + .../github.com/nbd-wtf/go-nostr/interface.go | 72 + vendor/github.com/nbd-wtf/go-nostr/justfile | 23 + vendor/github.com/nbd-wtf/go-nostr/keyer.go | 43 + vendor/github.com/nbd-wtf/go-nostr/keys.go | 49 + vendor/github.com/nbd-wtf/go-nostr/kinds.go | 152 + vendor/github.com/nbd-wtf/go-nostr/log.go | 14 + .../github.com/nbd-wtf/go-nostr/log_debug.go | 41 + .../github.com/nbd-wtf/go-nostr/log_normal.go | 6 + .../nbd-wtf/go-nostr/nip04/nip04.go | 116 + .../nbd-wtf/go-nostr/nip17/nip17.go | 175 + .../nbd-wtf/go-nostr/nip19/helpers.go | 34 + .../nbd-wtf/go-nostr/nip19/nip19.go | 245 + .../nbd-wtf/go-nostr/nip19/pointer.go | 49 + .../nbd-wtf/go-nostr/nip19/utils.go | 10 + .../nbd-wtf/go-nostr/nip44/README.md | 1 + .../nbd-wtf/go-nostr/nip44/nip44.go | 246 + .../go-nostr/nip45/hyperloglog/helpers.go | 30 + .../nbd-wtf/go-nostr/nip45/hyperloglog/hll.go | 115 + .../nbd-wtf/go-nostr/nip59/nip59.go | 100 + .../github.com/nbd-wtf/go-nostr/normalize.go | 114 + .../github.com/nbd-wtf/go-nostr/paginator.go | 68 + .../github.com/nbd-wtf/go-nostr/pointers.go | 175 + vendor/github.com/nbd-wtf/go-nostr/pool.go | 799 + vendor/github.com/nbd-wtf/go-nostr/relay.go | 578 + .../github.com/nbd-wtf/go-nostr/signature.go | 71 + .../go-nostr/signature_libsecp256k1.go | 104 + .../nbd-wtf/go-nostr/subscription.go | 194 + vendor/github.com/nbd-wtf/go-nostr/tags.go | 260 + .../github.com/nbd-wtf/go-nostr/timestamp.go | 13 + vendor/github.com/nbd-wtf/go-nostr/utils.go | 84 + .../github.com/puzpuzpuz/xsync/v3/.gitignore | 15 + .../puzpuzpuz/xsync/v3/BENCHMARKS.md | 133 + vendor/github.com/puzpuzpuz/xsync/v3/LICENSE | 201 + .../github.com/puzpuzpuz/xsync/v3/README.md | 195 + .../github.com/puzpuzpuz/xsync/v3/counter.go | 99 + vendor/github.com/puzpuzpuz/xsync/v3/map.go | 917 + vendor/github.com/puzpuzpuz/xsync/v3/mapof.go | 738 + .../puzpuzpuz/xsync/v3/mpmcqueue.go | 125 + .../puzpuzpuz/xsync/v3/mpmcqueueof.go | 138 + .../github.com/puzpuzpuz/xsync/v3/rbmutex.go | 188 + .../puzpuzpuz/xsync/v3/spscqueue.go | 92 + .../puzpuzpuz/xsync/v3/spscqueueof.go | 96 + vendor/github.com/puzpuzpuz/xsync/v3/util.go | 66 + .../puzpuzpuz/xsync/v3/util_hash.go | 77 + vendor/github.com/tidwall/gjson/README.md | 43 +- vendor/github.com/tidwall/gjson/SYNTAX.md | 32 +- vendor/github.com/tidwall/gjson/gjson.go | 498 +- vendor/github.com/tidwall/gjson/logo.png | Bin 15936 -> 0 bytes vendor/github.com/tidwall/pretty/README.md | 2 +- vendor/github.com/tidwall/pretty/pretty.go | 22 +- .../twitchyliquid64/golang-asm/LICENSE | 27 + .../golang-asm/asm/arch/arch.go | 716 + .../golang-asm/asm/arch/arm.go | 257 + .../golang-asm/asm/arch/arm64.go | 350 + .../golang-asm/asm/arch/mips.go | 72 + .../golang-asm/asm/arch/ppc64.go | 102 + .../golang-asm/asm/arch/riscv64.go | 28 + .../golang-asm/asm/arch/s390x.go | 81 + .../twitchyliquid64/golang-asm/bio/buf.go | 148 + .../golang-asm/bio/buf_mmap.go | 62 + .../golang-asm/bio/buf_nommap.go | 11 + .../twitchyliquid64/golang-asm/bio/must.go | 43 + .../twitchyliquid64/golang-asm/dwarf/dwarf.go | 1650 ++ .../golang-asm/dwarf/dwarf_defs.go | 493 + .../golang-asm/goobj/builtin.go | 45 + .../golang-asm/goobj/builtinlist.go | 245 + .../golang-asm/goobj/funcinfo.go | 233 + .../golang-asm/goobj/objfile.go | 871 + .../golang-asm/obj/abi_string.go | 16 + .../golang-asm/obj/addrtype_string.go | 16 + .../golang-asm/obj/arm/a.out.go | 410 + .../golang-asm/obj/arm/anames.go | 144 + .../golang-asm/obj/arm/anames5.go | 77 + .../golang-asm/obj/arm/asm5.go | 3096 ++++ .../golang-asm/obj/arm/list5.go | 124 + .../golang-asm/obj/arm/obj5.go | 784 + .../golang-asm/obj/arm64/a.out.go | 1033 ++ .../golang-asm/obj/arm64/anames.go | 512 + .../golang-asm/obj/arm64/anames7.go | 100 + .../golang-asm/obj/arm64/asm7.go | 7140 ++++++++ .../golang-asm/obj/arm64/doc.go | 249 + .../golang-asm/obj/arm64/list7.go | 288 + .../golang-asm/obj/arm64/obj7.go | 998 + .../golang-asm/obj/arm64/sysRegEnc.go | 895 + .../twitchyliquid64/golang-asm/obj/data.go | 200 + .../twitchyliquid64/golang-asm/obj/dwarf.go | 690 + .../twitchyliquid64/golang-asm/obj/go.go | 16 + .../twitchyliquid64/golang-asm/obj/inl.go | 131 + .../twitchyliquid64/golang-asm/obj/ld.go | 85 + .../twitchyliquid64/golang-asm/obj/line.go | 30 + .../twitchyliquid64/golang-asm/obj/link.go | 771 + .../golang-asm/obj/mips/a.out.go | 481 + .../golang-asm/obj/mips/anames.go | 135 + .../golang-asm/obj/mips/anames0.go | 45 + .../golang-asm/obj/mips/asm0.go | 2108 +++ .../golang-asm/obj/mips/list0.go | 83 + .../golang-asm/obj/mips/obj0.go | 1457 ++ .../twitchyliquid64/golang-asm/obj/objfile.go | 755 + .../twitchyliquid64/golang-asm/obj/pass.go | 176 + .../twitchyliquid64/golang-asm/obj/pcln.go | 413 + .../twitchyliquid64/golang-asm/obj/plist.go | 314 + .../golang-asm/obj/ppc64/a.out.go | 1032 ++ .../golang-asm/obj/ppc64/anames.go | 615 + .../golang-asm/obj/ppc64/anames9.go | 51 + .../golang-asm/obj/ppc64/asm9.go | 5367 ++++++ .../golang-asm/obj/ppc64/doc.go | 244 + .../golang-asm/obj/ppc64/list9.go | 104 + .../golang-asm/obj/ppc64/obj9.go | 1278 ++ .../golang-asm/obj/riscv/anames.go | 258 + .../golang-asm/obj/riscv/cpu.go | 644 + .../golang-asm/obj/riscv/inst.go | 459 + .../golang-asm/obj/riscv/list.go | 33 + .../golang-asm/obj/riscv/obj.go | 1999 ++ .../golang-asm/obj/s390x/a.out.go | 1003 + .../golang-asm/obj/s390x/anames.go | 720 + .../golang-asm/obj/s390x/anamesz.go | 39 + .../golang-asm/obj/s390x/asmz.go | 5043 +++++ .../golang-asm/obj/s390x/condition_code.go | 126 + .../golang-asm/obj/s390x/listz.go | 73 + .../golang-asm/obj/s390x/objz.go | 735 + .../golang-asm/obj/s390x/rotate.go | 47 + .../golang-asm/obj/s390x/vector.go | 1069 ++ .../twitchyliquid64/golang-asm/obj/sym.go | 421 + .../golang-asm/obj/textflag.go | 54 + .../twitchyliquid64/golang-asm/obj/util.go | 598 + .../golang-asm/obj/wasm/a.out.go | 331 + .../golang-asm/obj/wasm/anames.go | 208 + .../golang-asm/obj/wasm/wasmobj.go | 1185 ++ .../golang-asm/obj/x86/a.out.go | 423 + .../golang-asm/obj/x86/aenum.go | 1609 ++ .../golang-asm/obj/x86/anames.go | 1607 ++ .../golang-asm/obj/x86/asm6.go | 5446 ++++++ .../golang-asm/obj/x86/avx_optabs.go | 4628 +++++ .../golang-asm/obj/x86/evex.go | 382 + .../golang-asm/obj/x86/list6.go | 264 + .../golang-asm/obj/x86/obj6.go | 1261 ++ .../golang-asm/obj/x86/ytab.go | 44 + .../golang-asm/objabi/autotype.go | 38 + .../twitchyliquid64/golang-asm/objabi/flag.go | 162 + .../golang-asm/objabi/funcdata.go | 54 + .../golang-asm/objabi/funcid.go | 100 + .../twitchyliquid64/golang-asm/objabi/head.go | 109 + .../twitchyliquid64/golang-asm/objabi/line.go | 114 + .../twitchyliquid64/golang-asm/objabi/path.go | 41 + .../golang-asm/objabi/reloctype.go | 269 + .../golang-asm/objabi/reloctype_string.go | 17 + .../golang-asm/objabi/stack.go | 33 + .../golang-asm/objabi/symkind.go | 79 + .../golang-asm/objabi/symkind_string.go | 41 + .../golang-asm/objabi/typekind.go | 40 + .../twitchyliquid64/golang-asm/objabi/util.go | 203 + .../twitchyliquid64/golang-asm/src/pos.go | 470 + .../twitchyliquid64/golang-asm/src/xpos.go | 176 + .../twitchyliquid64/golang-asm/sys/arch.go | 187 + .../golang-asm/sys/supported.go | 116 + .../golang-asm/unsafeheader/unsafeheader.go | 37 + vendor/golang.org/x/arch/LICENSE | 27 + vendor/golang.org/x/arch/PATENTS | 22 + vendor/golang.org/x/arch/x86/x86asm/Makefile | 3 + vendor/golang.org/x/arch/x86/x86asm/decode.go | 1724 ++ vendor/golang.org/x/arch/x86/x86asm/gnu.go | 956 + vendor/golang.org/x/arch/x86/x86asm/inst.go | 649 + vendor/golang.org/x/arch/x86/x86asm/intel.go | 560 + vendor/golang.org/x/arch/x86/x86asm/plan9x.go | 392 + vendor/golang.org/x/arch/x86/x86asm/tables.go | 9924 ++++++++++ .../x/crypto/chacha20/chacha_arm64.go | 16 + .../x/crypto/chacha20/chacha_arm64.s | 307 + .../x/crypto/chacha20/chacha_generic.go | 398 + .../x/crypto/chacha20/chacha_noasm.go | 13 + .../x/crypto/chacha20/chacha_ppc64x.go | 16 + .../x/crypto/chacha20/chacha_ppc64x.s | 501 + .../x/crypto/chacha20/chacha_s390x.go | 27 + .../x/crypto/chacha20/chacha_s390x.s | 224 + vendor/golang.org/x/crypto/chacha20/xor.go | 42 + .../x/crypto/internal/alias/alias.go | 31 + .../x/crypto/internal/alias/alias_purego.go | 34 + vendor/golang.org/x/exp/LICENSE | 27 + vendor/golang.org/x/exp/PATENTS | 22 + .../x/exp/constraints/constraints.go | 54 + vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s | 17 + .../x/sys/cpu/asm_darwin_arm64_gc.s | 12 + .../golang.org/x/sys/cpu/asm_darwin_x86_gc.s | 17 + vendor/golang.org/x/sys/cpu/byteorder.go | 66 + vendor/golang.org/x/sys/cpu/cpu.go | 343 + vendor/golang.org/x/sys/cpu/cpu_aix.go | 33 + vendor/golang.org/x/sys/cpu/cpu_arm.go | 73 + vendor/golang.org/x/sys/cpu/cpu_arm64.go | 191 + vendor/golang.org/x/sys/cpu/cpu_arm64.s | 35 + .../golang.org/x/sys/cpu/cpu_darwin_arm64.go | 67 + .../x/sys/cpu/cpu_darwin_arm64_other.go | 31 + vendor/golang.org/x/sys/cpu/cpu_darwin_x86.go | 61 + vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go | 12 + vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go | 21 + vendor/golang.org/x/sys/cpu/cpu_gc_x86.go | 15 + vendor/golang.org/x/sys/cpu/cpu_gc_x86.s | 26 + .../golang.org/x/sys/cpu/cpu_gccgo_arm64.go | 12 + .../golang.org/x/sys/cpu/cpu_gccgo_s390x.go | 22 + vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c | 37 + vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go | 25 + vendor/golang.org/x/sys/cpu/cpu_linux.go | 15 + vendor/golang.org/x/sys/cpu/cpu_linux_arm.go | 39 + .../golang.org/x/sys/cpu/cpu_linux_arm64.go | 120 + .../golang.org/x/sys/cpu/cpu_linux_loong64.go | 22 + .../golang.org/x/sys/cpu/cpu_linux_mips64x.go | 22 + .../golang.org/x/sys/cpu/cpu_linux_noinit.go | 9 + .../golang.org/x/sys/cpu/cpu_linux_ppc64x.go | 30 + .../golang.org/x/sys/cpu/cpu_linux_riscv64.go | 162 + .../golang.org/x/sys/cpu/cpu_linux_s390x.go | 40 + vendor/golang.org/x/sys/cpu/cpu_loong64.go | 62 + vendor/golang.org/x/sys/cpu/cpu_loong64.s | 13 + vendor/golang.org/x/sys/cpu/cpu_mips64x.go | 15 + vendor/golang.org/x/sys/cpu/cpu_mipsx.go | 11 + .../golang.org/x/sys/cpu/cpu_netbsd_arm64.go | 173 + .../golang.org/x/sys/cpu/cpu_openbsd_arm64.go | 65 + .../golang.org/x/sys/cpu/cpu_openbsd_arm64.s | 11 + vendor/golang.org/x/sys/cpu/cpu_other_arm.go | 9 + .../golang.org/x/sys/cpu/cpu_other_arm64.go | 11 + .../golang.org/x/sys/cpu/cpu_other_mips64x.go | 11 + .../golang.org/x/sys/cpu/cpu_other_ppc64x.go | 12 + .../golang.org/x/sys/cpu/cpu_other_riscv64.go | 11 + vendor/golang.org/x/sys/cpu/cpu_other_x86.go | 11 + vendor/golang.org/x/sys/cpu/cpu_ppc64x.go | 16 + vendor/golang.org/x/sys/cpu/cpu_riscv64.go | 33 + vendor/golang.org/x/sys/cpu/cpu_s390x.go | 172 + vendor/golang.org/x/sys/cpu/cpu_s390x.s | 57 + vendor/golang.org/x/sys/cpu/cpu_wasm.go | 17 + vendor/golang.org/x/sys/cpu/cpu_windows.go | 26 + .../golang.org/x/sys/cpu/cpu_windows_arm64.go | 38 + vendor/golang.org/x/sys/cpu/cpu_x86.go | 236 + vendor/golang.org/x/sys/cpu/cpu_zos.go | 10 + vendor/golang.org/x/sys/cpu/cpu_zos_s390x.go | 25 + vendor/golang.org/x/sys/cpu/endian_big.go | 10 + vendor/golang.org/x/sys/cpu/endian_little.go | 10 + vendor/golang.org/x/sys/cpu/hwcap_linux.go | 71 + vendor/golang.org/x/sys/cpu/parse.go | 55 + .../x/sys/cpu/proc_cpuinfo_linux.go | 53 + vendor/golang.org/x/sys/cpu/runtime_auxv.go | 16 + .../x/sys/cpu/runtime_auxv_go121.go | 18 + .../golang.org/x/sys/cpu/syscall_aix_gccgo.go | 26 + .../x/sys/cpu/syscall_aix_ppc64_gc.go | 35 + .../x/sys/cpu/syscall_darwin_arm64_gc.go | 54 + .../x/sys/cpu/syscall_darwin_x86_gc.go | 98 + vendor/golang.org/x/sys/cpu/zcpu_windows.go | 48 + vendor/modules.txt | 139 +- 919 files changed, 360626 insertions(+), 220 deletions(-) create mode 100644 irc/nostr/dm.go create mode 100644 irc/nostr/errors.go create mode 100644 irc/nostr/nip05.go create mode 100644 irc/nostr/nostr.go create mode 100644 irc/nostr/relay.go create mode 100644 vendor/github.com/ImVexed/fasturl/.gitignore create mode 100644 vendor/github.com/ImVexed/fasturl/LICENSE create mode 100644 vendor/github.com/ImVexed/fasturl/Makefile create mode 100644 vendor/github.com/ImVexed/fasturl/parser.go create mode 100644 vendor/github.com/ImVexed/fasturl/parser.rl create mode 100644 vendor/github.com/ImVexed/fasturl/parser_fuzz.go create mode 100644 vendor/github.com/ImVexed/fasturl/readme.md create mode 100644 vendor/github.com/btcsuite/btcd/btcec/v2/LICENSE create mode 100644 vendor/github.com/btcsuite/btcd/btcec/v2/README.md create mode 100644 vendor/github.com/btcsuite/btcd/btcec/v2/btcec.go create mode 100644 vendor/github.com/btcsuite/btcd/btcec/v2/ciphering.go create mode 100644 vendor/github.com/btcsuite/btcd/btcec/v2/curve.go create mode 100644 vendor/github.com/btcsuite/btcd/btcec/v2/doc.go create mode 100644 vendor/github.com/btcsuite/btcd/btcec/v2/error.go create mode 100644 vendor/github.com/btcsuite/btcd/btcec/v2/field.go create mode 100644 vendor/github.com/btcsuite/btcd/btcec/v2/modnscalar.go create mode 100644 vendor/github.com/btcsuite/btcd/btcec/v2/privkey.go create mode 100644 vendor/github.com/btcsuite/btcd/btcec/v2/pubkey.go create mode 100644 vendor/github.com/btcsuite/btcd/btcec/v2/schnorr/error.go create mode 100644 vendor/github.com/btcsuite/btcd/btcec/v2/schnorr/pubkey.go create mode 100644 vendor/github.com/btcsuite/btcd/btcec/v2/schnorr/signature.go create mode 100644 vendor/github.com/btcsuite/btcd/btcutil/LICENSE create mode 100644 vendor/github.com/btcsuite/btcd/btcutil/bech32/README.md create mode 100644 vendor/github.com/btcsuite/btcd/btcutil/bech32/bech32.go create mode 100644 vendor/github.com/btcsuite/btcd/btcutil/bech32/doc.go create mode 100644 vendor/github.com/btcsuite/btcd/btcutil/bech32/error.go create mode 100644 vendor/github.com/btcsuite/btcd/btcutil/bech32/version.go create mode 100644 vendor/github.com/btcsuite/btcd/chaincfg/chainhash/LICENSE create mode 100644 vendor/github.com/btcsuite/btcd/chaincfg/chainhash/README.md create mode 100644 vendor/github.com/btcsuite/btcd/chaincfg/chainhash/doc.go create mode 100644 vendor/github.com/btcsuite/btcd/chaincfg/chainhash/hash.go create mode 100644 vendor/github.com/btcsuite/btcd/chaincfg/chainhash/hashfuncs.go create mode 100644 vendor/github.com/bytedance/sonic/LICENSE create mode 100644 vendor/github.com/bytedance/sonic/ast/api.go create mode 100644 vendor/github.com/bytedance/sonic/ast/api_compat.go create mode 100644 vendor/github.com/bytedance/sonic/ast/asm.s create mode 100644 vendor/github.com/bytedance/sonic/ast/buffer.go create mode 100644 vendor/github.com/bytedance/sonic/ast/decode.go create mode 100644 vendor/github.com/bytedance/sonic/ast/encode.go create mode 100644 vendor/github.com/bytedance/sonic/ast/error.go create mode 100644 vendor/github.com/bytedance/sonic/ast/iterator.go create mode 100644 vendor/github.com/bytedance/sonic/ast/node.go create mode 100644 vendor/github.com/bytedance/sonic/ast/parser.go create mode 100644 vendor/github.com/bytedance/sonic/ast/search.go create mode 100644 vendor/github.com/bytedance/sonic/ast/stubs.go create mode 100644 vendor/github.com/bytedance/sonic/ast/visitor.go create mode 100644 vendor/github.com/bytedance/sonic/encoder/encoder_compat.go create mode 100644 vendor/github.com/bytedance/sonic/encoder/encoder_native.go create mode 100644 vendor/github.com/bytedance/sonic/internal/caching/asm.s create mode 100644 vendor/github.com/bytedance/sonic/internal/caching/fcache.go create mode 100644 vendor/github.com/bytedance/sonic/internal/caching/hashing.go create mode 100644 vendor/github.com/bytedance/sonic/internal/caching/pcache.go create mode 100644 vendor/github.com/bytedance/sonic/internal/compat/warn.go create mode 100644 vendor/github.com/bytedance/sonic/internal/cpu/features.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/alg/mapiter.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/alg/opts.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/alg/primitives.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/alg/sort.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/alg/spec.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/alg/spec_compat.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/compiler.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/encode_norace.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/encode_race.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/encoder.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/ir/op.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/pools_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/pools_compt.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/stream.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/vars/cache.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/vars/const.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/vars/errors.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/vars/stack.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/vars/types.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/vm/stbus.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/vm/vm.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/x86/asm_stubs_amd64_go117.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/x86/asm_stubs_amd64_go121.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/x86/assembler_regabi_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/x86/debug_go116.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/x86/debug_go117.go create mode 100644 vendor/github.com/bytedance/sonic/internal/encoder/x86/stbus.go create mode 100644 vendor/github.com/bytedance/sonic/internal/jit/arch_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/jit/asm.s create mode 100644 vendor/github.com/bytedance/sonic/internal/jit/assembler_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/jit/backend.go create mode 100644 vendor/github.com/bytedance/sonic/internal/jit/runtime.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/f32toa.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/f32toa_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/f32toa_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/f64toa.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/f64toa_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/f64toa_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/get_by_path.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/get_by_path_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/get_by_path_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/html_escape.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/html_escape_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/html_escape_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/i64toa.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/i64toa_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/i64toa_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/lookup_small_key.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/lookup_small_key_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/lookup_small_key_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/lspace.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/lspace_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/lspace_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/native_export.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/parse_with_padding.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/parse_with_padding_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/parse_with_padding_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/quote.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/quote_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/quote_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/skip_array.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/skip_array_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/skip_array_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/skip_number.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/skip_number_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/skip_number_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/skip_object.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/skip_object_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/skip_object_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/skip_one.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/skip_one_fast.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/skip_one_fast_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/skip_one_fast_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/skip_one_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/skip_one_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/u64toa.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/u64toa_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/u64toa_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/unquote.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/unquote_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/unquote_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/validate_one.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/validate_one_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/validate_one_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/validate_utf8.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/validate_utf8_fast.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/validate_utf8_fast_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/validate_utf8_fast_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/validate_utf8_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/validate_utf8_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/value.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/value_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/value_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/vnumber.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/vnumber_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/vnumber_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/vsigned.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/vsigned_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/vsigned_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/vstring.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/vstring_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/vstring_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/vunsigned.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/vunsigned_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/avx2/vunsigned_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/dispatch_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/dispatch_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/f32toa.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/f64toa.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/fastfloat_test.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/fastint_test.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/get_by_path.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/html_escape.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/i64toa.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/lookup_small_key.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/lspace.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/native_export.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/native_test.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/f32toa_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/f32toa_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/f32toa_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/f64toa_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/f64toa_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/f64toa_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/get_by_path_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/get_by_path_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/get_by_path_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/html_escape_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/html_escape_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/html_escape_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/i64toa_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/i64toa_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/i64toa_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/lookup_small_key_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/lookup_small_key_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/lookup_small_key_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/lspace_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/lspace_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/lspace_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/native_export_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/parse_with_padding_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/parse_with_padding_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/parse_with_padding_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/quote_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/quote_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/quote_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/skip_array_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/skip_array_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/skip_array_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/skip_number_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/skip_number_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/skip_number_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/skip_object_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/skip_object_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/skip_object_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/skip_one_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/skip_one_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/skip_one_fast_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/skip_one_fast_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/skip_one_fast_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/skip_one_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/u64toa_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/u64toa_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/u64toa_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/unquote_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/unquote_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/unquote_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/validate_one_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/validate_one_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/validate_one_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/validate_utf8_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/validate_utf8_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/validate_utf8_fast_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/validate_utf8_fast_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/validate_utf8_fast_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/validate_utf8_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/value_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/value_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/value_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/vnumber_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/vnumber_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/vnumber_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/vsigned_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/vsigned_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/vsigned_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/vstring_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/vstring_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/vstring_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/vunsigned_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/vunsigned_arm64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/native/neon/vunsigned_subr_arm64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/parse_with_padding.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/quote.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/recover_test.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/skip_array.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/skip_number.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/skip_object.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/skip_one.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/skip_one_fast.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/f32toa.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/f32toa_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/f32toa_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/f64toa.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/f64toa_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/f64toa_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/get_by_path.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/get_by_path_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/get_by_path_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/html_escape.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/html_escape_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/html_escape_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/i64toa.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/i64toa_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/i64toa_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/lookup_small_key.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/lookup_small_key_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/lookup_small_key_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/lspace.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/lspace_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/lspace_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/native_export.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/parse_with_padding.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/parse_with_padding_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/parse_with_padding_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/quote.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/quote_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/quote_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/skip_array.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/skip_array_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/skip_array_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/skip_number.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/skip_number_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/skip_number_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/skip_object.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/skip_object_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/skip_object_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/skip_one.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/skip_one_fast.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/skip_one_fast_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/skip_one_fast_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/skip_one_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/skip_one_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/u64toa.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/u64toa_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/u64toa_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/unquote.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/unquote_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/unquote_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/validate_one.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/validate_one_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/validate_one_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/validate_utf8.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/validate_utf8_fast.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/validate_utf8_fast_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/validate_utf8_fast_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/validate_utf8_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/validate_utf8_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/value.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/value_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/value_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/vnumber.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/vnumber_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/vnumber_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/vsigned.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/vsigned_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/vsigned_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/vstring.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/vstring_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/vstring_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/vunsigned.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/vunsigned_subr.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/sse/vunsigned_text_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/traceback_test.mock_tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/types/types.go create mode 100644 vendor/github.com/bytedance/sonic/internal/native/u64toa.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/unquote.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/validate_one.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/validate_utf8.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/validate_utf8_fast.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/value.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/vnumber.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/vsigned.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/vstring.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/native/vunsigned.tmpl create mode 100644 vendor/github.com/bytedance/sonic/internal/resolver/asm.s create mode 100644 vendor/github.com/bytedance/sonic/internal/resolver/resolver.go create mode 100644 vendor/github.com/bytedance/sonic/internal/resolver/stubs_go120.go create mode 100644 vendor/github.com/bytedance/sonic/internal/resolver/stubs_go123.go create mode 100644 vendor/github.com/bytedance/sonic/internal/resolver/stubs_latest.go create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/asm_amd64.s create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/asm_compat.s create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/assertI2I.go create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/base64_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/base64_compat.go create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/fastconv.go create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/fastmem.go create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/fastvalue.go create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/gcwb.go create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/gcwb_legacy.go create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/growslice.go create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/growslice_legacy.go create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/int48.go create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/map_legacy.go create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/map_nosiwss_go124.go create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/map_siwss_go124.go create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/pool.go create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/stubs.go create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/table.go create mode 100644 vendor/github.com/bytedance/sonic/internal/rt/types.go create mode 100644 vendor/github.com/bytedance/sonic/internal/utils/skip.go create mode 100644 vendor/github.com/bytedance/sonic/loader/LICENSE create mode 100644 vendor/github.com/bytedance/sonic/loader/funcdata.go create mode 100644 vendor/github.com/bytedance/sonic/loader/funcdata_compat.go create mode 100644 vendor/github.com/bytedance/sonic/loader/funcdata_go117.go create mode 100644 vendor/github.com/bytedance/sonic/loader/funcdata_go118.go create mode 100644 vendor/github.com/bytedance/sonic/loader/funcdata_go120.go create mode 100644 vendor/github.com/bytedance/sonic/loader/funcdata_go121.go create mode 100644 vendor/github.com/bytedance/sonic/loader/funcdata_go123.go create mode 100644 vendor/github.com/bytedance/sonic/loader/funcdata_latest.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/abi/abi.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/abi/abi_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/abi/abi_legacy_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/abi/abi_regabi_amd64.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/abi/stubs.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/ast.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/errors.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/ops.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/parser.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/pools.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/term.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/expr/utils.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/arch.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/asm.s create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/eface.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/encodings.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/instructions.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/instructions_table.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/operands.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/pools.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/program.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/registers.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/iasm/x86_64/utils.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/rt/fastmem.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/rt/fastvalue.go create mode 100644 vendor/github.com/bytedance/sonic/loader/internal/rt/stackmap.go create mode 100644 vendor/github.com/bytedance/sonic/loader/loader.go create mode 100644 vendor/github.com/bytedance/sonic/loader/loader_latest.go create mode 100644 vendor/github.com/bytedance/sonic/loader/mmap_unix.go create mode 100644 vendor/github.com/bytedance/sonic/loader/mmap_windows.go create mode 100644 vendor/github.com/bytedance/sonic/loader/pcdata.go create mode 100644 vendor/github.com/bytedance/sonic/loader/register.go create mode 100644 vendor/github.com/bytedance/sonic/loader/register_tango.go create mode 100644 vendor/github.com/bytedance/sonic/loader/stubs.go create mode 100644 vendor/github.com/bytedance/sonic/loader/wrapper.go create mode 100644 vendor/github.com/bytedance/sonic/option/option.go create mode 100644 vendor/github.com/bytedance/sonic/unquote/unquote.go create mode 100644 vendor/github.com/bytedance/sonic/utf8/utf8.go create mode 100644 vendor/github.com/cloudwego/base64x/.gitignore create mode 100644 vendor/github.com/cloudwego/base64x/.gitmodules create mode 100644 vendor/github.com/cloudwego/base64x/.golangci.yaml create mode 100644 vendor/github.com/cloudwego/base64x/.licenserc.yaml create mode 100644 vendor/github.com/cloudwego/base64x/CODE_OF_CONDUCT.md create mode 100644 vendor/github.com/cloudwego/base64x/CONTRIBUTING.md create mode 100644 vendor/github.com/cloudwego/base64x/LICENSE create mode 100644 vendor/github.com/cloudwego/base64x/LICENSE-APACHE create mode 100644 vendor/github.com/cloudwego/base64x/Makefile create mode 100644 vendor/github.com/cloudwego/base64x/README.md create mode 100644 vendor/github.com/cloudwego/base64x/_typos.toml create mode 100644 vendor/github.com/cloudwego/base64x/base64x.go create mode 100644 vendor/github.com/cloudwego/base64x/base64x_subr_amd64.go create mode 100644 vendor/github.com/cloudwego/base64x/check_branch_name.sh create mode 100644 vendor/github.com/cloudwego/base64x/faststr.go create mode 100644 vendor/github.com/cloudwego/base64x/internal/native/avx2/b64decode.go create mode 100644 vendor/github.com/cloudwego/base64x/internal/native/avx2/b64decode_subr.go create mode 100644 vendor/github.com/cloudwego/base64x/internal/native/avx2/b64decode_text_amd64.go create mode 100644 vendor/github.com/cloudwego/base64x/internal/native/avx2/b64encode.go create mode 100644 vendor/github.com/cloudwego/base64x/internal/native/avx2/b64encode_subr.go create mode 100644 vendor/github.com/cloudwego/base64x/internal/native/avx2/b64encode_text_amd64.go create mode 100644 vendor/github.com/cloudwego/base64x/internal/native/avx2/native_export.go create mode 100644 vendor/github.com/cloudwego/base64x/internal/native/b64decode.tmpl create mode 100644 vendor/github.com/cloudwego/base64x/internal/native/b64encode.tmpl create mode 100644 vendor/github.com/cloudwego/base64x/internal/native/dispatch.go create mode 100644 vendor/github.com/cloudwego/base64x/internal/native/native_export.tmpl create mode 100644 vendor/github.com/cloudwego/base64x/internal/native/sse/b64decode.go create mode 100644 vendor/github.com/cloudwego/base64x/internal/native/sse/b64decode_subr.go create mode 100644 vendor/github.com/cloudwego/base64x/internal/native/sse/b64decode_text_amd64.go create mode 100644 vendor/github.com/cloudwego/base64x/internal/native/sse/b64encode.go create mode 100644 vendor/github.com/cloudwego/base64x/internal/native/sse/b64encode_subr.go create mode 100644 vendor/github.com/cloudwego/base64x/internal/native/sse/b64encode_text_amd64.go create mode 100644 vendor/github.com/cloudwego/base64x/internal/native/sse/native_export.go create mode 100644 vendor/github.com/cloudwego/base64x/internal/rt/asm_amd64.s create mode 100644 vendor/github.com/cloudwego/base64x/internal/rt/asm_arm64.s create mode 100644 vendor/github.com/cloudwego/base64x/internal/rt/fastmem.go create mode 100644 vendor/github.com/coder/websocket/LICENSE.txt create mode 100644 vendor/github.com/coder/websocket/README.md create mode 100644 vendor/github.com/coder/websocket/accept.go create mode 100644 vendor/github.com/coder/websocket/close.go create mode 100644 vendor/github.com/coder/websocket/compress.go create mode 100644 vendor/github.com/coder/websocket/conn.go create mode 100644 vendor/github.com/coder/websocket/dial.go create mode 100644 vendor/github.com/coder/websocket/doc.go create mode 100644 vendor/github.com/coder/websocket/frame.go create mode 100644 vendor/github.com/coder/websocket/internal/bpool/bpool.go create mode 100644 vendor/github.com/coder/websocket/internal/errd/wrap.go create mode 100644 vendor/github.com/coder/websocket/internal/util/util.go create mode 100644 vendor/github.com/coder/websocket/internal/wsjs/wsjs_js.go create mode 100644 vendor/github.com/coder/websocket/internal/xsync/go.go create mode 100644 vendor/github.com/coder/websocket/internal/xsync/int64.go create mode 100644 vendor/github.com/coder/websocket/make.sh create mode 100644 vendor/github.com/coder/websocket/mask.go create mode 100644 vendor/github.com/coder/websocket/mask_amd64.s create mode 100644 vendor/github.com/coder/websocket/mask_arm64.s create mode 100644 vendor/github.com/coder/websocket/mask_asm.go create mode 100644 vendor/github.com/coder/websocket/mask_go.go create mode 100644 vendor/github.com/coder/websocket/netconn.go create mode 100644 vendor/github.com/coder/websocket/netconn_js.go create mode 100644 vendor/github.com/coder/websocket/netconn_notjs.go create mode 100644 vendor/github.com/coder/websocket/read.go create mode 100644 vendor/github.com/coder/websocket/stringer.go create mode 100644 vendor/github.com/coder/websocket/write.go create mode 100644 vendor/github.com/coder/websocket/ws_js.go create mode 100644 vendor/github.com/decred/dcrd/crypto/blake256/LICENSE create mode 100644 vendor/github.com/decred/dcrd/crypto/blake256/README.md create mode 100644 vendor/github.com/decred/dcrd/crypto/blake256/error.go create mode 100644 vendor/github.com/decred/dcrd/crypto/blake256/hasher.go create mode 100644 vendor/github.com/decred/dcrd/crypto/blake256/hasher224.go create mode 100644 vendor/github.com/decred/dcrd/crypto/blake256/hasher256.go create mode 100644 vendor/github.com/decred/dcrd/crypto/blake256/internal/compress/README.md create mode 100644 vendor/github.com/decred/dcrd/crypto/blake256/internal/compress/blocks_amd64.go create mode 100644 vendor/github.com/decred/dcrd/crypto/blake256/internal/compress/blocks_amd64.s create mode 100644 vendor/github.com/decred/dcrd/crypto/blake256/internal/compress/blocks_generic.go create mode 100644 vendor/github.com/decred/dcrd/crypto/blake256/internal/compress/blocks_noasm.go create mode 100644 vendor/github.com/decred/dcrd/crypto/blake256/internal/compress/blocksisa_amd64.go create mode 100644 vendor/github.com/decred/dcrd/crypto/blake256/internal/compress/cpu_amd64.go create mode 100644 vendor/github.com/decred/dcrd/crypto/blake256/internal/compress/cpu_amd64.s create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/LICENSE create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/README.md create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/compressedbytepoints.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve_embedded.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/curve_precompute.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/doc.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ecdh.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/ellipticadaptor.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/error.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/field.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/loadprecomputed.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/modnscalar.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/nonce.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/privkey.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/pubkey.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/schnorr/README.md create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/schnorr/doc.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/schnorr/error.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/schnorr/pubkey.go create mode 100644 vendor/github.com/decred/dcrd/dcrec/secp256k1/v4/schnorr/signature.go create mode 100644 vendor/github.com/josharian/intern/README.md create mode 100644 vendor/github.com/josharian/intern/intern.go create mode 100644 vendor/github.com/josharian/intern/license.md create mode 100644 vendor/github.com/json-iterator/go/.codecov.yml create mode 100644 vendor/github.com/json-iterator/go/.gitignore create mode 100644 vendor/github.com/json-iterator/go/.travis.yml create mode 100644 vendor/github.com/json-iterator/go/Gopkg.lock create mode 100644 vendor/github.com/json-iterator/go/Gopkg.toml create mode 100644 vendor/github.com/json-iterator/go/LICENSE create mode 100644 vendor/github.com/json-iterator/go/README.md create mode 100644 vendor/github.com/json-iterator/go/adapter.go create mode 100644 vendor/github.com/json-iterator/go/any.go create mode 100644 vendor/github.com/json-iterator/go/any_array.go create mode 100644 vendor/github.com/json-iterator/go/any_bool.go create mode 100644 vendor/github.com/json-iterator/go/any_float.go create mode 100644 vendor/github.com/json-iterator/go/any_int32.go create mode 100644 vendor/github.com/json-iterator/go/any_int64.go create mode 100644 vendor/github.com/json-iterator/go/any_invalid.go create mode 100644 vendor/github.com/json-iterator/go/any_nil.go create mode 100644 vendor/github.com/json-iterator/go/any_number.go create mode 100644 vendor/github.com/json-iterator/go/any_object.go create mode 100644 vendor/github.com/json-iterator/go/any_str.go create mode 100644 vendor/github.com/json-iterator/go/any_uint32.go create mode 100644 vendor/github.com/json-iterator/go/any_uint64.go create mode 100644 vendor/github.com/json-iterator/go/build.sh create mode 100644 vendor/github.com/json-iterator/go/config.go create mode 100644 vendor/github.com/json-iterator/go/fuzzy_mode_convert_table.md create mode 100644 vendor/github.com/json-iterator/go/iter.go create mode 100644 vendor/github.com/json-iterator/go/iter_array.go create mode 100644 vendor/github.com/json-iterator/go/iter_float.go create mode 100644 vendor/github.com/json-iterator/go/iter_int.go create mode 100644 vendor/github.com/json-iterator/go/iter_object.go create mode 100644 vendor/github.com/json-iterator/go/iter_skip.go create mode 100644 vendor/github.com/json-iterator/go/iter_skip_sloppy.go create mode 100644 vendor/github.com/json-iterator/go/iter_skip_strict.go create mode 100644 vendor/github.com/json-iterator/go/iter_str.go create mode 100644 vendor/github.com/json-iterator/go/jsoniter.go create mode 100644 vendor/github.com/json-iterator/go/pool.go create mode 100644 vendor/github.com/json-iterator/go/reflect.go create mode 100644 vendor/github.com/json-iterator/go/reflect_array.go create mode 100644 vendor/github.com/json-iterator/go/reflect_dynamic.go create mode 100644 vendor/github.com/json-iterator/go/reflect_extension.go create mode 100644 vendor/github.com/json-iterator/go/reflect_json_number.go create mode 100644 vendor/github.com/json-iterator/go/reflect_json_raw_message.go create mode 100644 vendor/github.com/json-iterator/go/reflect_map.go create mode 100644 vendor/github.com/json-iterator/go/reflect_marshaler.go create mode 100644 vendor/github.com/json-iterator/go/reflect_native.go create mode 100644 vendor/github.com/json-iterator/go/reflect_optional.go create mode 100644 vendor/github.com/json-iterator/go/reflect_slice.go create mode 100644 vendor/github.com/json-iterator/go/reflect_struct_decoder.go create mode 100644 vendor/github.com/json-iterator/go/reflect_struct_encoder.go create mode 100644 vendor/github.com/json-iterator/go/stream.go create mode 100644 vendor/github.com/json-iterator/go/stream_float.go create mode 100644 vendor/github.com/json-iterator/go/stream_int.go create mode 100644 vendor/github.com/json-iterator/go/stream_str.go create mode 100644 vendor/github.com/json-iterator/go/test.sh create mode 100644 vendor/github.com/klauspost/cpuid/v2/.gitignore create mode 100644 vendor/github.com/klauspost/cpuid/v2/.goreleaser.yml create mode 100644 vendor/github.com/klauspost/cpuid/v2/CONTRIBUTING.txt create mode 100644 vendor/github.com/klauspost/cpuid/v2/LICENSE create mode 100644 vendor/github.com/klauspost/cpuid/v2/README.md create mode 100644 vendor/github.com/klauspost/cpuid/v2/cpuid.go create mode 100644 vendor/github.com/klauspost/cpuid/v2/cpuid_386.s create mode 100644 vendor/github.com/klauspost/cpuid/v2/cpuid_amd64.s create mode 100644 vendor/github.com/klauspost/cpuid/v2/cpuid_arm64.s create mode 100644 vendor/github.com/klauspost/cpuid/v2/detect_arm64.go create mode 100644 vendor/github.com/klauspost/cpuid/v2/detect_ref.go create mode 100644 vendor/github.com/klauspost/cpuid/v2/detect_x86.go create mode 100644 vendor/github.com/klauspost/cpuid/v2/featureid_string.go create mode 100644 vendor/github.com/klauspost/cpuid/v2/os_darwin_arm64.go create mode 100644 vendor/github.com/klauspost/cpuid/v2/os_linux_arm64.go create mode 100644 vendor/github.com/klauspost/cpuid/v2/os_other_arm64.go create mode 100644 vendor/github.com/klauspost/cpuid/v2/os_safe_linux_arm64.go create mode 100644 vendor/github.com/klauspost/cpuid/v2/os_unsafe_linux_arm64.go create mode 100644 vendor/github.com/klauspost/cpuid/v2/test-architectures.sh create mode 100644 vendor/github.com/mailru/easyjson/.gitignore create mode 100644 vendor/github.com/mailru/easyjson/LICENSE create mode 100644 vendor/github.com/mailru/easyjson/Makefile create mode 100644 vendor/github.com/mailru/easyjson/README.md create mode 100644 vendor/github.com/mailru/easyjson/buffer/pool.go create mode 100644 vendor/github.com/mailru/easyjson/helpers.go create mode 100644 vendor/github.com/mailru/easyjson/jlexer/bytestostr.go create mode 100644 vendor/github.com/mailru/easyjson/jlexer/bytestostr_nounsafe.go create mode 100644 vendor/github.com/mailru/easyjson/jlexer/error.go create mode 100644 vendor/github.com/mailru/easyjson/jlexer/lexer.go create mode 100644 vendor/github.com/mailru/easyjson/jwriter/writer.go create mode 100644 vendor/github.com/mailru/easyjson/raw.go create mode 100644 vendor/github.com/mailru/easyjson/unknown_fields.go create mode 100644 vendor/github.com/modern-go/concurrent/.gitignore create mode 100644 vendor/github.com/modern-go/concurrent/.travis.yml create mode 100644 vendor/github.com/modern-go/concurrent/LICENSE create mode 100644 vendor/github.com/modern-go/concurrent/README.md create mode 100644 vendor/github.com/modern-go/concurrent/executor.go create mode 100644 vendor/github.com/modern-go/concurrent/go_above_19.go create mode 100644 vendor/github.com/modern-go/concurrent/go_below_19.go create mode 100644 vendor/github.com/modern-go/concurrent/log.go create mode 100644 vendor/github.com/modern-go/concurrent/test.sh create mode 100644 vendor/github.com/modern-go/concurrent/unbounded_executor.go create mode 100644 vendor/github.com/modern-go/reflect2/.gitignore create mode 100644 vendor/github.com/modern-go/reflect2/.travis.yml create mode 100644 vendor/github.com/modern-go/reflect2/Gopkg.lock create mode 100644 vendor/github.com/modern-go/reflect2/Gopkg.toml create mode 100644 vendor/github.com/modern-go/reflect2/LICENSE create mode 100644 vendor/github.com/modern-go/reflect2/README.md create mode 100644 vendor/github.com/modern-go/reflect2/go_above_118.go create mode 100644 vendor/github.com/modern-go/reflect2/go_above_19.go create mode 100644 vendor/github.com/modern-go/reflect2/go_below_118.go create mode 100644 vendor/github.com/modern-go/reflect2/reflect2.go create mode 100644 vendor/github.com/modern-go/reflect2/reflect2_amd64.s create mode 100644 vendor/github.com/modern-go/reflect2/reflect2_kind.go create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_386.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_amd64p32.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_arm.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_arm64.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_mips64x.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_mipsx.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_ppc64x.s create mode 100644 vendor/github.com/modern-go/reflect2/relfect2_s390x.s create mode 100644 vendor/github.com/modern-go/reflect2/safe_field.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_map.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_slice.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_struct.go create mode 100644 vendor/github.com/modern-go/reflect2/safe_type.go create mode 100644 vendor/github.com/modern-go/reflect2/type_map.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_array.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_eface.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_field.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_iface.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_link.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_map.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_ptr.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_slice.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_struct.go create mode 100644 vendor/github.com/modern-go/reflect2/unsafe_type.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/.gitignore create mode 100644 vendor/github.com/nbd-wtf/go-nostr/LICENSE.md create mode 100644 vendor/github.com/nbd-wtf/go-nostr/README.md create mode 100644 vendor/github.com/nbd-wtf/go-nostr/connection.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/connection_options.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/connection_options_js.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/envelopes.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/envelopes_default.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/envelopes_sonic.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/event.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/event_easyjson.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/filter.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/filter_easyjson.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/helpers.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/interface.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/justfile create mode 100644 vendor/github.com/nbd-wtf/go-nostr/keyer.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/keys.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/kinds.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/log.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/log_debug.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/log_normal.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/nip04/nip04.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/nip17/nip17.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/nip19/helpers.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/nip19/nip19.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/nip19/pointer.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/nip19/utils.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/nip44/README.md create mode 100644 vendor/github.com/nbd-wtf/go-nostr/nip44/nip44.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/nip45/hyperloglog/helpers.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/nip45/hyperloglog/hll.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/nip59/nip59.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/normalize.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/paginator.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/pointers.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/pool.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/relay.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/signature.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/signature_libsecp256k1.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/subscription.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/tags.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/timestamp.go create mode 100644 vendor/github.com/nbd-wtf/go-nostr/utils.go create mode 100644 vendor/github.com/puzpuzpuz/xsync/v3/.gitignore create mode 100644 vendor/github.com/puzpuzpuz/xsync/v3/BENCHMARKS.md create mode 100644 vendor/github.com/puzpuzpuz/xsync/v3/LICENSE create mode 100644 vendor/github.com/puzpuzpuz/xsync/v3/README.md create mode 100644 vendor/github.com/puzpuzpuz/xsync/v3/counter.go create mode 100644 vendor/github.com/puzpuzpuz/xsync/v3/map.go create mode 100644 vendor/github.com/puzpuzpuz/xsync/v3/mapof.go create mode 100644 vendor/github.com/puzpuzpuz/xsync/v3/mpmcqueue.go create mode 100644 vendor/github.com/puzpuzpuz/xsync/v3/mpmcqueueof.go create mode 100644 vendor/github.com/puzpuzpuz/xsync/v3/rbmutex.go create mode 100644 vendor/github.com/puzpuzpuz/xsync/v3/spscqueue.go create mode 100644 vendor/github.com/puzpuzpuz/xsync/v3/spscqueueof.go create mode 100644 vendor/github.com/puzpuzpuz/xsync/v3/util.go create mode 100644 vendor/github.com/puzpuzpuz/xsync/v3/util_hash.go delete mode 100644 vendor/github.com/tidwall/gjson/logo.png create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/LICENSE create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/asm/arch/arch.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/asm/arch/arm.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/asm/arch/arm64.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/asm/arch/mips.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/asm/arch/ppc64.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/asm/arch/riscv64.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/asm/arch/s390x.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/bio/buf.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/bio/buf_mmap.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/bio/buf_nommap.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/bio/must.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/dwarf/dwarf.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/dwarf/dwarf_defs.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/goobj/builtin.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/goobj/builtinlist.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/goobj/funcinfo.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/goobj/objfile.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/abi_string.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/addrtype_string.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/arm/a.out.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/arm/anames.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/arm/anames5.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/arm/asm5.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/arm/list5.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/arm/obj5.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/a.out.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/anames.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/anames7.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/asm7.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/doc.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/list7.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/obj7.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/arm64/sysRegEnc.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/data.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/dwarf.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/go.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/inl.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/ld.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/line.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/link.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/mips/a.out.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/mips/anames.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/mips/anames0.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/mips/asm0.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/mips/list0.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/mips/obj0.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/objfile.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/pass.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/pcln.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/plist.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/ppc64/a.out.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/ppc64/anames.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/ppc64/anames9.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/ppc64/asm9.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/ppc64/doc.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/ppc64/list9.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/ppc64/obj9.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/riscv/anames.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/riscv/cpu.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/riscv/inst.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/riscv/list.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/riscv/obj.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/s390x/a.out.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/s390x/anames.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/s390x/anamesz.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/s390x/asmz.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/s390x/condition_code.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/s390x/listz.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/s390x/objz.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/s390x/rotate.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/s390x/vector.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/sym.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/textflag.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/util.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/wasm/a.out.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/wasm/anames.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/wasm/wasmobj.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/x86/a.out.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/x86/aenum.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/x86/anames.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/x86/asm6.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/x86/avx_optabs.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/x86/evex.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/x86/list6.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/x86/obj6.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/obj/x86/ytab.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/objabi/autotype.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/objabi/flag.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/objabi/funcdata.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/objabi/funcid.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/objabi/head.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/objabi/line.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/objabi/path.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/objabi/reloctype.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/objabi/reloctype_string.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/objabi/stack.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/objabi/symkind.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/objabi/symkind_string.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/objabi/typekind.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/objabi/util.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/src/pos.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/src/xpos.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/sys/arch.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/sys/supported.go create mode 100644 vendor/github.com/twitchyliquid64/golang-asm/unsafeheader/unsafeheader.go create mode 100644 vendor/golang.org/x/arch/LICENSE create mode 100644 vendor/golang.org/x/arch/PATENTS create mode 100644 vendor/golang.org/x/arch/x86/x86asm/Makefile create mode 100644 vendor/golang.org/x/arch/x86/x86asm/decode.go create mode 100644 vendor/golang.org/x/arch/x86/x86asm/gnu.go create mode 100644 vendor/golang.org/x/arch/x86/x86asm/inst.go create mode 100644 vendor/golang.org/x/arch/x86/x86asm/intel.go create mode 100644 vendor/golang.org/x/arch/x86/x86asm/plan9x.go create mode 100644 vendor/golang.org/x/arch/x86/x86asm/tables.go create mode 100644 vendor/golang.org/x/crypto/chacha20/chacha_arm64.go create mode 100644 vendor/golang.org/x/crypto/chacha20/chacha_arm64.s create mode 100644 vendor/golang.org/x/crypto/chacha20/chacha_generic.go create mode 100644 vendor/golang.org/x/crypto/chacha20/chacha_noasm.go create mode 100644 vendor/golang.org/x/crypto/chacha20/chacha_ppc64x.go create mode 100644 vendor/golang.org/x/crypto/chacha20/chacha_ppc64x.s create mode 100644 vendor/golang.org/x/crypto/chacha20/chacha_s390x.go create mode 100644 vendor/golang.org/x/crypto/chacha20/chacha_s390x.s create mode 100644 vendor/golang.org/x/crypto/chacha20/xor.go create mode 100644 vendor/golang.org/x/crypto/internal/alias/alias.go create mode 100644 vendor/golang.org/x/crypto/internal/alias/alias_purego.go create mode 100644 vendor/golang.org/x/exp/LICENSE create mode 100644 vendor/golang.org/x/exp/PATENTS create mode 100644 vendor/golang.org/x/exp/constraints/constraints.go create mode 100644 vendor/golang.org/x/sys/cpu/asm_aix_ppc64.s create mode 100644 vendor/golang.org/x/sys/cpu/asm_darwin_arm64_gc.s create mode 100644 vendor/golang.org/x/sys/cpu/asm_darwin_x86_gc.s create mode 100644 vendor/golang.org/x/sys/cpu/byteorder.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_aix.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_arm.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_arm64.s create mode 100644 vendor/golang.org/x/sys/cpu/cpu_darwin_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_darwin_arm64_other.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_darwin_x86.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gc_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gc_s390x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gc_x86.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gc_x86.s create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gccgo_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gccgo_s390x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.c create mode 100644 vendor/golang.org/x/sys/cpu/cpu_gccgo_x86.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_arm.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_loong64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_mips64x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_noinit.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_ppc64x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_riscv64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_linux_s390x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_loong64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_loong64.s create mode 100644 vendor/golang.org/x/sys/cpu/cpu_mips64x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_mipsx.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_netbsd_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_openbsd_arm64.s create mode 100644 vendor/golang.org/x/sys/cpu/cpu_other_arm.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_other_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_other_mips64x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_other_ppc64x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_other_riscv64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_other_x86.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_ppc64x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_riscv64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_s390x.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_s390x.s create mode 100644 vendor/golang.org/x/sys/cpu/cpu_wasm.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_windows.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_windows_arm64.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_x86.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_zos.go create mode 100644 vendor/golang.org/x/sys/cpu/cpu_zos_s390x.go create mode 100644 vendor/golang.org/x/sys/cpu/endian_big.go create mode 100644 vendor/golang.org/x/sys/cpu/endian_little.go create mode 100644 vendor/golang.org/x/sys/cpu/hwcap_linux.go create mode 100644 vendor/golang.org/x/sys/cpu/parse.go create mode 100644 vendor/golang.org/x/sys/cpu/proc_cpuinfo_linux.go create mode 100644 vendor/golang.org/x/sys/cpu/runtime_auxv.go create mode 100644 vendor/golang.org/x/sys/cpu/runtime_auxv_go121.go create mode 100644 vendor/golang.org/x/sys/cpu/syscall_aix_gccgo.go create mode 100644 vendor/golang.org/x/sys/cpu/syscall_aix_ppc64_gc.go create mode 100644 vendor/golang.org/x/sys/cpu/syscall_darwin_arm64_gc.go create mode 100644 vendor/golang.org/x/sys/cpu/syscall_darwin_x86_gc.go create mode 100644 vendor/golang.org/x/sys/cpu/zcpu_windows.go diff --git a/default.yaml b/default.yaml index ea1e5029..b6d00943 100644 --- a/default.yaml +++ b/default.yaml @@ -366,6 +366,10 @@ server: # all users will receive simply `netname` as their cloaked hostname. num-bits: 64 + # enable nostr-based hostnames for accounts registered with nostr verification + # (e.g., alice@example.com -> alice.example.com, npub1abc123... -> npub1abc123.nostr) + nostr-hostnames: true + # secure-nets identifies IPs and CIDRs which are secure at layer 3, # for example, because they are on a trusted internal LAN or a VPN. # plaintext connections from these IPs and CIDRs will be considered @@ -477,6 +481,19 @@ accounts: # time for which a password reset code is valid timeout: 1d + # options for nostr-based verification of account registrations + nostr-verification: + enabled: true + # hex-encoded private key for signing DMs (generate with: openssl rand -hex 32) + private-key: "" + # default relays to use for sending DMs and relay discovery + default-relays: + - "wss://relay.damus.io" + - "wss://nos.lol" + - "wss://profiles.nostr1.com" + # timeout for nostr operations (NIP-05 resolution, relay connections) + timeout: 30s + # throttle account login attempts (to prevent either password guessing, or DoS # attacks on the server aimed at forcing repeated expensive bcrypt computations) login-throttling: diff --git a/go.mod b/go.mod index 461c550a..e99521ed 100644 --- a/go.mod +++ b/go.mod @@ -11,10 +11,8 @@ require ( github.com/ergochat/irc-go v0.5.0 github.com/go-sql-driver/mysql v1.10.0 github.com/gofrs/flock v0.8.1 - github.com/gorilla/websocket v1.4.2 + github.com/gorilla/websocket v1.5.0 github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd - github.com/onsi/ginkgo v1.12.0 // indirect - github.com/onsi/gomega v1.9.0 // indirect github.com/tidwall/buntdb v1.3.2 github.com/xdg-go/scram v1.0.2 golang.org/x/crypto v0.54.0 @@ -28,29 +26,50 @@ require ( github.com/ergochat/webpush-go/v2 v2.0.0 github.com/golang-jwt/jwt/v5 v5.3.1 github.com/jackc/pgx/v5 v5.10.0 + github.com/nbd-wtf/go-nostr v0.52.0 modernc.org/sqlite v1.54.0 ) require ( filippo.io/edwards25519 v1.2.0 // indirect + github.com/ImVexed/fasturl v0.0.0-20230304231329-4e41488060f3 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect + github.com/btcsuite/btcd/btcutil v1.1.5 // indirect + github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect + github.com/bytedance/sonic v1.13.1 // indirect + github.com/bytedance/sonic/loader v0.2.4 // indirect + github.com/cloudwego/base64x v0.1.5 // indirect + github.com/coder/websocket v1.8.12 // indirect + github.com/decred/dcrd/crypto/blake256 v1.1.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/google/uuid v1.6.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/cpuid/v2 v2.2.10 // indirect github.com/kr/text v0.2.0 // indirect + github.com/mailru/easyjson v0.9.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect github.com/ncruces/go-strftime v1.0.0 // indirect + github.com/puzpuzpuz/xsync/v3 v3.5.1 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rogpeppe/go-internal v1.6.1 // indirect github.com/tidwall/btree v1.4.2 // indirect - github.com/tidwall/gjson v1.14.3 // indirect + github.com/tidwall/gjson v1.18.0 // indirect github.com/tidwall/grect v0.1.4 // indirect github.com/tidwall/match v1.1.1 // indirect - github.com/tidwall/pretty v1.2.0 // indirect + github.com/tidwall/pretty v1.2.1 // indirect github.com/tidwall/rtred v0.1.2 // indirect github.com/tidwall/tinyqueue v0.1.1 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect + golang.org/x/arch v0.15.0 // indirect + golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect golang.org/x/sync v0.22.0 // indirect golang.org/x/sys v0.47.0 // indirect modernc.org/libc v1.74.1 // indirect diff --git a/go.sum b/go.sum index 3e5436e0..e06aa092 100644 --- a/go.sum +++ b/go.sum @@ -4,14 +4,60 @@ filippo.io/edwards25519 v1.2.0 h1:crnVqOiS4jqYleHd9vaKZ+HKtHfllngJIiOpNpoJsjo= filippo.io/edwards25519 v1.2.0/go.mod h1:xzAOLCNug/yB62zG1bQ8uziwrIqIuxhctzJT18Q77mc= github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962 h1:KeNholpO2xKjgaaSyd+DyQRrsQjhbSeS7qe4nEw8aQw= github.com/GehirnInc/crypt v0.0.0-20200316065508-bb7000b8a962/go.mod h1:kC29dT1vFpj7py2OvG1khBdQpo3kInWP+6QipLbdngo= +github.com/ImVexed/fasturl v0.0.0-20230304231329-4e41488060f3 h1:ClzzXMDDuUbWfNNZqGeYq4PnYOlwlOVIvSyNaIy0ykg= +github.com/ImVexed/fasturl v0.0.0-20230304231329-4e41488060f3/go.mod h1:we0YA5CsBbH5+/NUzC/AlMmxaDtWlXeNsqrwXjTzmzA= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= +github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A= +github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= +github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= +github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= +github.com/btcsuite/btcd/btcutil v1.1.5 h1:+wER79R5670vs/ZusMTF1yTcRYE5GUsFbdjdisflzM8= +github.com/btcsuite/btcd/btcutil v1.1.5/go.mod h1:PSZZ4UitpLBWzxGd5VGOrLnmOjtPP/a6HaFo12zMs00= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/bytedance/sonic v1.13.1 h1:Jyd5CIvdFnkOWuKXr+wm4Nyk2h0yAFsr8ucJgEasO3g= +github.com/bytedance/sonic v1.13.1/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.4 h1:ZWCw4stuXUsn1/+zQDqeE7JKP+QO47tz7QCNan80NzY= +github.com/bytedance/sonic/loader v0.2.4/go.mod h1:N8A3vUdtUebEY2/VQC0MyhYeKUFosQU6FxH2JmUe6VI= +github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4= +github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo= +github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8= +github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= +github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815 h1:bWDMxwH3px2JBh6AyO7hdCn/PkvCZXii8TGj7sbtEbQ= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/dvyukov/go-fuzz v0.0.0-20200318091601-be3528f3a813/go.mod h1:11Gm+ccJnvAhCNLlf5+cS9KjtbaD5I5zaZpFMsTHWTw= github.com/emersion/go-msgauth v0.7.0 h1:vj2hMn6KhFtW41kshIBTXvp6KgYSqpA/ZN9Pv4g1INc= github.com/emersion/go-msgauth v0.7.0/go.mod h1:mmS9I6HkSovrNgq0HNXTeu8l3sRAAuQ9RMvbM4KU7Ck= github.com/ergochat/confusables v0.0.0-20201108231250-4ab98ab61fb1 h1:WLHTOodthVyv5NvYLIvWl112kSFv5IInKKrRN2qpons= @@ -27,6 +73,8 @@ github.com/ergochat/webpush-go/v2 v2.0.0/go.mod h1:OQlhnq8JeHDzRzAy6bdDObr19uqbH github.com/ergochat/websocket v1.4.2-oragono1 h1:plMUunFBM6UoSCIYCKKclTdy/TkkHfUslhOfJQzfueM= github.com/ergochat/websocket v1.4.2-oragono1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/go-sql-driver/mysql v1.10.0 h1:Q+1LV8DkHJvSYAdR83XzuhDaTykuDx0l6fkXxoWCWfw= github.com/go-sql-driver/mysql v1.10.0/go.mod h1:M+cqaI7+xxXGG9swrdeUIoPG3Y3KCkF0pZej+SK+nWk= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= @@ -34,13 +82,23 @@ github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14j github.com/golang-jwt/jwt/v5 v5.3.1 h1:kYf81DTWFe7t+1VvL7eS+jKFVWaUnK9cB1qbwn63YCY= github.com/golang-jwt/jwt/v5 v5.3.1/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs= github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= -github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= @@ -50,6 +108,18 @@ github.com/jackc/pgx/v5 v5.10.0 h1:VhSvgU2jSli8o3AqIEOTJr7rZwAEUVo4E4XhR94Zfr0= github.com/jackc/pgx/v5 v5.10.0/go.mod h1:mal1tBGAFfLHvZzaYh77YS/eC6IX9OWbRV1QIIM0Jn4= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= +github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= @@ -57,29 +127,53 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/nbd-wtf/go-nostr v0.52.0 h1:9gtz0VOUPOb0PC2kugr2WJAxThlCSSM62t5VC3tvk1g= +github.com/nbd-wtf/go-nostr v0.52.0/go.mod h1:4avYoc9mDGZ9wHsvCOhHH9vPzKucCfuYBtJUSpHTfNk= github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w= github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= +github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd h1:+iAPaTbi1gZpcpDwe/BW1fx7Xoesv69hLNGPheoyhBs= github.com/okzk/sdnotify v0.0.0-20180710141335-d9becc38acbd/go.mod h1:4soZNh0zW0LtYGdQ416i0jO0EIqMGcbtaspRS4BDvRQ= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU= -github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg= -github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++5Fg= +github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/go-internal v1.6.1 h1:/FiVV8dS/e+YqF2JvO3yXRFbBLTIuSDkuC7aBOAvL+k= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tidwall/assert v0.1.0 h1:aWcKyRBUAdLoVebxo95N7+YZVTFF/ASTr7BN4sLP6XI= github.com/tidwall/assert v0.1.0/go.mod h1:QLYtGyeqse53vuELQheYl9dngGCJQ+mTtlxcktb+Kj8= github.com/tidwall/btree v1.4.2 h1:PpkaieETJMUxYNADsjgtNRcERX7mGc/GP2zp/r5FM3g= @@ -87,60 +181,91 @@ github.com/tidwall/btree v1.4.2/go.mod h1:LGm8L/DZjPLmeWGjv5kFrY8dL4uVhMmzmmLYms github.com/tidwall/buntdb v1.3.2 h1:qd+IpdEGs0pZci37G4jF51+fSKlkuUTMXuHhXL1AkKg= github.com/tidwall/buntdb v1.3.2/go.mod h1:lZZrZUWzlyDJKlLQ6DKAy53LnG7m5kHyrEHvvcDmBpU= github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= -github.com/tidwall/gjson v1.14.3 h1:9jvXn7olKEHU1S9vwoMGliaT8jq1vJ7IH/n9zD9Dnlw= -github.com/tidwall/gjson v1.14.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/grect v0.1.4 h1:dA3oIgNgWdSspFzn1kS4S/RDpZFLrIxAZOdJKjYapOg= github.com/tidwall/grect v0.1.4/go.mod h1:9FBsaYRaR0Tcy4UwefBX/UDcDcDy9V5jUcxHzv2jd5Q= github.com/tidwall/lotsa v1.0.2 h1:dNVBH5MErdaQ/xd9s769R31/n2dXavsQ0Yf4TMEHHw8= github.com/tidwall/lotsa v1.0.2/go.mod h1:X6NiU+4yHA3fE3Puvpnn1XMDrFZrE9JO2/w+UMuqgR8= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs= github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/rtred v0.1.2 h1:exmoQtOLvDoO8ud++6LwVsAMTu0KPzLTUrMln8u1yu8= github.com/tidwall/rtred v0.1.2/go.mod h1:hd69WNXQ5RP9vHd7dqekAz+RIdtfBogmglkZSRxCHFQ= github.com/tidwall/tinyqueue v0.1.1 h1:SpNEvEggbpyN5DIReaJ2/1ndroY8iyEGxPYxoSaymYE= github.com/tidwall/tinyqueue v0.1.1/go.mod h1:O/QNHwrnjqr6IHItYrzoHAKYhBkLI67Q096fQP5zMYw= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/stringprep v1.0.2 h1:6iq84/ryjjeRmMJwxutI51F2GIPlP5BfTvXHeYjyhBc= github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +golang.org/x/arch v0.15.0 h1:QtOrQd0bTUnhNVNndMpLHNWrDmYzZ2KDqSrEymqInZw= +golang.org/x/arch v0.15.0/go.mod h1:JmwW7aLIoRUKgaTzhkiEFxvcEiQGyOg9BMonBJUS7EE= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= +golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw= +golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM= golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= +golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o= golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek= golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs= golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0= golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs= golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q= golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -174,3 +299,4 @@ modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0= modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A= modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y= modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= diff --git a/irc/accounts.go b/irc/accounts.go index dd8dab61..d1ad32e3 100644 --- a/irc/accounts.go +++ b/irc/accounts.go @@ -25,6 +25,7 @@ import ( "github.com/ergochat/ergo/irc/email" "github.com/ergochat/ergo/irc/migrations" "github.com/ergochat/ergo/irc/modes" + "github.com/ergochat/ergo/irc/nostr" "github.com/ergochat/ergo/irc/oauth2" "github.com/ergochat/ergo/irc/passwd" "github.com/ergochat/ergo/irc/utils" @@ -54,6 +55,7 @@ const ( keyAccountChannelToModes = "account.channeltomodes %s" keyAccountPushSubscriptions = "account.pushsubscriptions %s" keyAccountMetadata = "account.metadata %s" + keyAccountNostrIdentifier = "account.nostridentifier %s" // stores the nostr identifier used during registration maxCertfpsPerAccount = 5 ) @@ -865,11 +867,74 @@ func (am *AccountManager) dispatchCallback(client *Client, account string, callb return "", nil } else if callbackNamespace == "mailto" { return am.dispatchMailtoCallback(client, account, callbackValue) + } else if callbackNamespace == "nostr" { + return am.dispatchNostrCallback(client, account, callbackValue) } else { return "", fmt.Errorf("Callback not implemented: %s", callbackNamespace) } } +func (am *AccountManager) dispatchNostrCallback(_ *Client, account string, callbackValue string) (code string, err error) { + config := am.server.Config().Accounts.Registration.NostrVerification + if !config.Enabled { + return "", fmt.Errorf("Nostr verification is not enabled") + } + + code = utils.GenerateSecretToken() + + // Create DM config from server config + dmConfig := nostr.DMConfig{ + PrivateKey: config.PrivateKey, + DefaultRelays: config.DefaultRelays, + Timeout: time.Duration(config.Timeout), + UserAgent: fmt.Sprintf("Ergo IRC Server %s", am.server.Config().Server.Name), + } + + // Send the verification DM + err = nostr.SendVerificationDM(callbackValue, account, code, am.server.Config().Server.Name, dmConfig) + if err != nil { + am.server.logger.Error("internal", "Failed to dispatch nostr DM to", callbackValue, err.Error()) + return "", err + } + + // Save the nostr identifier for hostname generation + am.saveNostrIdentifier(account, callbackValue) + + return code, nil +} + +func (am *AccountManager) saveNostrIdentifier(account string, nostrIdentifier string) { + key := fmt.Sprintf(keyAccountNostrIdentifier, account) + am.server.store.Update(func(tx *buntdb.Tx) error { + tx.Set(key, nostrIdentifier, nil) + return nil + }) +} + +func (am *AccountManager) loadNostrIdentifier(account string) (nostrIdentifier string) { + key := fmt.Sprintf(keyAccountNostrIdentifier, account) + am.server.store.View(func(tx *buntdb.Tx) error { + nostrIdentifier, _ = tx.Get(key) + return nil + }) + return +} + +// ComputeNostrHostname generates a nostr-based hostname for an account if available +func (am *AccountManager) ComputeNostrHostname(accountName string) string { + config := am.server.Config() + if !config.Server.Cloaks.NostrHostnames { + return "" + } + + nostrIdentifier := am.loadNostrIdentifier(accountName) + if nostrIdentifier == "" { + return "" + } + + return config.Server.Cloaks.ComputeNostrHostname(nostrIdentifier) +} + func (am *AccountManager) dispatchMailtoCallback(client *Client, account string, callbackValue string) (code string, err error) { config := am.server.Config().Accounts.Registration.EmailVerification code = utils.GenerateSecretToken() @@ -1918,6 +1983,7 @@ func (am *AccountManager) Unregister(account string, erase bool) error { emailChangeKey := fmt.Sprintf(keyAccountEmailChange, casefoldedAccount) pushSubscriptionsKey := fmt.Sprintf(keyAccountPushSubscriptions, casefoldedAccount) metadataKey := fmt.Sprintf(keyAccountMetadata, casefoldedAccount) + nostrIdentifierKey := fmt.Sprintf(keyAccountNostrIdentifier, casefoldedAccount) var clients []*Client defer func() { @@ -1978,6 +2044,7 @@ func (am *AccountManager) Unregister(account string, erase bool) error { tx.Delete(emailChangeKey) tx.Delete(pushSubscriptionsKey) tx.Delete(metadataKey) + tx.Delete(nostrIdentifierKey) return nil }) diff --git a/irc/client.go b/irc/client.go index 00b156eb..6548c930 100644 --- a/irc/client.go +++ b/irc/client.go @@ -451,7 +451,13 @@ func (server *Server) AddAlwaysOnClient(account ClientAccount, channelToStatus m rawHostname, cloakedHostname := server.name, "" if config.Server.Cloaks.EnabledForAlwaysOn { - cloakedHostname = config.Server.Cloaks.ComputeAccountCloak(account.Name) + // Try nostr hostname first, fallback to regular account cloak + if config.Server.Cloaks.NostrHostnames { + cloakedHostname = server.accounts.ComputeNostrHostname(account.Name) + } + if cloakedHostname == "" { + cloakedHostname = config.Server.Cloaks.ComputeAccountCloak(account.Name) + } } username := "~u" diff --git a/irc/cloaks/cloaks.go b/irc/cloaks/cloaks.go index 5ebc0937..470dd6c7 100644 --- a/irc/cloaks/cloaks.go +++ b/irc/cloaks/cloaks.go @@ -5,9 +5,11 @@ package cloaks import ( "fmt" "net" + "strings" "crypto/sha3" + "github.com/ergochat/ergo/irc/nostr" "github.com/ergochat/ergo/irc/utils" ) @@ -19,6 +21,7 @@ type CloakConfig struct { CidrLenIPv6 int `yaml:"cidr-len-ipv6"` NumBits int `yaml:"num-bits"` LegacySecretValue string `yaml:"secret"` + NostrHostnames bool `yaml:"nostr-hostnames"` // enable nostr-based hostnames for accounts registered with nostr secret string numBytes int @@ -93,3 +96,40 @@ func (config *CloakConfig) ComputeAccountCloak(accountName string) string { copy(paddedAccountName[16:], accountName[:]) return config.macAndCompose(paddedAccountName) } + +// ComputeNostrHostname generates a readable hostname from a nostr identifier +func (config *CloakConfig) ComputeNostrHostname(nostrIdentifier string) string { + if nostrIdentifier == "" { + return config.Netname + } + + // Handle NIP-05 addresses (alice@example.com -> alice@example.com) + if strings.Contains(nostrIdentifier, "@") { + parts := strings.SplitN(nostrIdentifier, "@", 2) + if len(parts) == 2 { + // Return the full NIP-05 address as the hostname + return nostrIdentifier + } + } + + // Handle npub format (npub1abc123... -> npub1abc123....nostr) + if strings.HasPrefix(nostrIdentifier, "npub1") { + // Use the full npub as hostname + return fmt.Sprintf("%s.nostr", nostrIdentifier) + } + + // Handle hex pubkey (3bf0c63f... -> convert to npub and use full npub.nostr) + if len(nostrIdentifier) == 64 { + // Convert hex pubkey to npub format + npub, err := nostr.HexToNpub(nostrIdentifier) + if err != nil { + // Fallback to truncated hex if conversion fails + truncated := nostrIdentifier[:8] + return fmt.Sprintf("%s.nostr", truncated) + } + return fmt.Sprintf("%s.nostr", npub) + } + + // Fallback to regular account cloak + return config.ComputeAccountCloak(nostrIdentifier) +} diff --git a/irc/config.go b/irc/config.go index 7a149491..af477735 100644 --- a/irc/config.go +++ b/irc/config.go @@ -406,6 +406,13 @@ type AccountRegistrationConfig struct { Throttling ThrottleConfig // new-style (v2.4 email verification config): EmailVerification email.MailtoConfig `yaml:"email-verification"` + // nostr-based account verification, where we send a DM with verification code + NostrVerification struct { + Enabled bool `yaml:"enabled"` + PrivateKey string `yaml:"private-key"` + DefaultRelays []string `yaml:"default-relays"` + Timeout time.Duration `yaml:"timeout"` + } `yaml:"nostr-verification"` // old-style email verification config, with "callbacks": LegacyEnabledCallbacks []string `yaml:"enabled-callbacks"` LegacyCallbacks struct { diff --git a/irc/errors.go b/irc/errors.go index 9231d034..b2c64808 100644 --- a/irc/errors.go +++ b/irc/errors.go @@ -31,6 +31,8 @@ var ( errAccountSuspended = errors.New(`Account has been suspended`) errAccountVerificationFailed = errors.New("Account verification failed") errAccountVerificationInvalidCode = errors.New("Invalid account verification code") + errValidNostrIdentifierRequired = errors.New("A valid nostr identifier is required") + errUnsupportedCallbackNamespace = errors.New("Unsupported callback namespace") errAccountUpdateFailed = errors.New(`Error while updating your account information`) errAccountMustHoldNick = errors.New(`You must hold that nickname in order to register it`) errAuthRequired = errors.New("You must be logged into an account to do this") diff --git a/irc/handlers.go b/irc/handlers.go index 47d92cc0..1ee56a6a 100644 --- a/irc/handlers.go +++ b/irc/handlers.go @@ -32,6 +32,7 @@ import ( "github.com/ergochat/ergo/irc/history" "github.com/ergochat/ergo/irc/jwt" "github.com/ergochat/ergo/irc/modes" + "github.com/ergochat/ergo/irc/nostr" "github.com/ergochat/ergo/irc/oauth2" "github.com/ergochat/ergo/irc/sno" "github.com/ergochat/ergo/irc/utils" @@ -48,25 +49,42 @@ var ( func parseCallback(spec string, config *Config) (callbackNamespace string, callbackValue string, err error) { // XXX if we don't require verification, ignore any callback that was passed here // (to avoid confusion in the case where the ircd has no mail server configured) - if !config.Accounts.Registration.EmailVerification.Enabled { + if !config.Accounts.Registration.EmailVerification.Enabled && !config.Accounts.Registration.NostrVerification.Enabled { callbackNamespace = "*" return } - callback := strings.ToLower(spec) - if colonIndex := strings.IndexByte(callback, ':'); colonIndex != -1 { - callbackNamespace, callbackValue = callback[:colonIndex], callback[colonIndex+1:] + if colonIndex := strings.IndexByte(spec, ':'); colonIndex != -1 { + callbackNamespace, callbackValue = strings.ToLower(spec[:colonIndex]), spec[colonIndex+1:] } else { - // "If a callback namespace is not ... provided, the IRC server MUST use mailto"" - callbackNamespace = "mailto" - callbackValue = callback + // Auto-detect callback type based on format + if nostr.IsNostrIdentifier(spec) { + callbackNamespace = "nostr" + callbackValue = spec + } else { + // "If a callback namespace is not ... provided, the IRC server MUST use mailto"" + callbackNamespace = "mailto" + callbackValue = strings.ToLower(spec) + } } - if config.Accounts.Registration.EmailVerification.Enabled { - if callbackNamespace != "mailto" { - err = errValidEmailRequired - } else if strings.IndexByte(callbackValue, '@') < 1 { - err = errValidEmailRequired + if callbackNamespace == "mailto" { + if config.Accounts.Registration.EmailVerification.Enabled { + if strings.IndexByte(callbackValue, '@') < 1 { + err = errValidEmailRequired + } + } else { + err = errUnsupportedCallbackNamespace } + } else if callbackNamespace == "nostr" { + if config.Accounts.Registration.NostrVerification.Enabled { + if !nostr.IsValidNostrIdentifier(callbackValue) { + err = errValidNostrIdentifierRequired + } + } else { + err = errUnsupportedCallbackNamespace + } + } else if callbackNamespace != "admin" && callbackNamespace != "none" && callbackNamespace != "*" { + err = errUnsupportedCallbackNamespace } return @@ -137,7 +155,14 @@ func sendSuccessfulAccountAuth(service *ircService, client *Client, rb *Response if rb.session.isTor { config := client.server.Config() if config.Server.Cloaks.EnabledForAlwaysOn { - cloakedHostname := config.Server.Cloaks.ComputeAccountCloak(details.accountName) + // Try nostr hostname first, fallback to regular account cloak + var cloakedHostname string + if config.Server.Cloaks.NostrHostnames { + cloakedHostname = client.server.accounts.ComputeNostrHostname(details.accountName) + } + if cloakedHostname == "" { + cloakedHostname = config.Server.Cloaks.ComputeAccountCloak(details.accountName) + } client.setCloakedHostname(cloakedHostname) if client.registered { client.sendChghost(details.nickMask, client.Hostname()) diff --git a/irc/nickserv.go b/irc/nickserv.go index dd1ee166..7a6e15b4 100644 --- a/irc/nickserv.go +++ b/irc/nickserv.go @@ -135,11 +135,18 @@ INFO gives you information about the given (or your own) user account.`, handler: nsRegisterHandler, // TODO: "email" is an oversimplification here; it's actually any callback, e.g., // person@example.com, mailto:person@example.com, tel:16505551234. - help: `Syntax: $bREGISTER [email]$b + help: `Syntax: $bREGISTER [nostr-identifier]$b -REGISTER lets you register your current nickname as a user account. If the -server allows anonymous registration, you can omit the e-mail address. +REGISTER lets you register your current nickname as a user account using nostr +verification. You can provide a nostr identifier in one of these formats: +• NIP-05 address: alice@example.com +• npub key: npub1abc123def456... +• hex pubkey: 3bf0c63fcb93c5ef2f068d70b8d70d963b649d75... + +The server will contact you via Nostr DM (nip17 or nip04) with verification code. + +If the server allows anonymous registration, you can omit the nostr identifier. If you are currently logged in with a TLS client certificate and wish to use it instead of a password to log in, send * as the password.`, helpShort: `$bREGISTER$b lets you register a user account.`, @@ -1018,7 +1025,7 @@ func nsRegisterHandler(service *ircService, server *Server, client *Client, comm callbackNamespace, callbackValue, validationErr := parseCallback(email, config) if validationErr != nil { - service.Notice(rb, client.t("Registration requires a valid e-mail address")) + service.Notice(rb, client.t("Registration invalid, see help")) return } diff --git a/irc/nostr/dm.go b/irc/nostr/dm.go new file mode 100644 index 00000000..5d8ce5e0 --- /dev/null +++ b/irc/nostr/dm.go @@ -0,0 +1,319 @@ +// Copyright (c) 2024 Ergo Contributors +// released under the MIT license + +package nostr + +import ( + "context" + "fmt" + "log" + "strings" + "time" + + "github.com/nbd-wtf/go-nostr" + "github.com/nbd-wtf/go-nostr/nip04" + "github.com/nbd-wtf/go-nostr/nip17" + "github.com/nbd-wtf/go-nostr/nip44" +) + +// DMConfig holds configuration for DM operations +type DMConfig struct { + PrivateKey string // Hex-encoded private key for signing + DefaultRelays []string // Fallback relays if none discovered + Timeout time.Duration // Timeout for relay operations + UserAgent string // User agent for HTTP requests +} + +// SimpleKeyer implements nostr.Keyer interface for NIP-17 +type SimpleKeyer struct { + privateKey string +} + +func (k *SimpleKeyer) GetPublicKey(ctx context.Context) (string, error) { + return nostr.GetPublicKey(k.privateKey) +} + +func (k *SimpleKeyer) SignEvent(ctx context.Context, event *nostr.Event) error { + return event.Sign(k.privateKey) +} + +func (k *SimpleKeyer) Encrypt(ctx context.Context, plaintext, recipientPubkey string) (string, error) { + // Generate conversation key using NIP-44 + conversationKey, err := nip44.GenerateConversationKey(recipientPubkey, k.privateKey) + if err != nil { + return "", err + } + return nip44.Encrypt(plaintext, conversationKey) +} + +func (k *SimpleKeyer) Decrypt(ctx context.Context, ciphertext, senderPubkey string) (string, error) { + // Generate conversation key using NIP-44 + conversationKey, err := nip44.GenerateConversationKey(senderPubkey, k.privateKey) + if err != nil { + return "", err + } + return nip44.Decrypt(ciphertext, conversationKey) +} + +// CreateNIP04DM creates a NIP-04 DM event with verification code +func CreateNIP04DM(recipientPubkey, senderPrivkey, account, code, serverName string) (*nostr.Event, error) { + // Create the message content + message := fmt.Sprintf("Account verification for %s\n\nAccount: %s\nVerification code: %s\n\nTo verify your account, issue the following command:\n/MSG NickServ VERIFY %s %s", + serverName, account, code, account, code) + + // Compute shared secret for NIP-04 encryption + sharedSecret, err := nip04.ComputeSharedSecret(recipientPubkey, senderPrivkey) + if err != nil { + return nil, fmt.Errorf("%w: failed to compute shared secret: %v", ErrDMEncryptionFailed, err) + } + + // Encrypt the message using NIP-04 + encryptedContent, err := nip04.Encrypt(message, sharedSecret) + if err != nil { + return nil, fmt.Errorf("%w: %v", ErrDMEncryptionFailed, err) + } + + // Get sender pubkey from private key + senderPubkey, err := nostr.GetPublicKey(senderPrivkey) + if err != nil { + return nil, fmt.Errorf("failed to derive public key: %w", err) + } + + // Create the event + event := &nostr.Event{ + PubKey: senderPubkey, + CreatedAt: nostr.Timestamp(time.Now().Unix()), + Kind: 4, // NIP-04 DM event kind + Tags: nostr.Tags{ + {"p", recipientPubkey}, + }, + Content: encryptedContent, + } + + // Sign the event + if err := event.Sign(senderPrivkey); err != nil { + return nil, err + } + + return event, nil +} + +// CreateNIP17DM creates a NIP-17 DM event with verification code +func CreateNIP17DM(recipientPubkey, senderPrivkey, account, code, serverName string) (*nostr.Event, error) { + // Create the message content + message := fmt.Sprintf("Account verification for %s\n\nAccount: %s\nVerification code: %s\n\nTo verify your account, issue the following command:\n/MSG NickServ VERIFY %s %s", + serverName, account, code, account, code) + + // Create a SimpleKeyer instance + keyer := &SimpleKeyer{privateKey: senderPrivkey} + + // Use nip17.PrepareMessage to create properly gift-wrapped events + ctx := context.Background() + _, toThem, err := nip17.PrepareMessage( + ctx, + message, + nostr.Tags{}, // empty tags, the function will add the "p" tag + keyer, + recipientPubkey, + nil, // no modify function + ) + if err != nil { + return nil, fmt.Errorf("%w: %v", ErrDMEncryptionFailed, err) + } + + // Return the toThem event (the one that goes to the recipient) + return &toThem, nil +} + +// SendVerificationDM sends a verification DM to a user +func SendVerificationDM(identifier, account, code, serverName string, config DMConfig) error { + if config.PrivateKey == "" { + return ErrNostrKeyNotConfigured + } + + ctx, cancel := context.WithTimeout(context.Background(), config.Timeout) + defer cancel() + + // Resolve the identifier to a pubkey + nip05Config := NIP05Config{ + Timeout: config.Timeout, + UserAgent: config.UserAgent, + } + + pubkey, nip05Relays, err := ResolvePubkey(identifier, nip05Config) + if err != nil { + return fmt.Errorf("failed to resolve pubkey: %w", err) + } + + // Discover inbox relays + relayConfig := RelayConfig{ + DefaultRelays: config.DefaultRelays, + Timeout: config.Timeout, + MaxRelays: 10, + } + + // Combine NIP-05 relays with discovered relays + allRelays := append(nip05Relays, config.DefaultRelays...) + if len(allRelays) > 0 { + relayConfig.DefaultRelays = allRelays + } + + // Check if user has private relays (NIP-50 kind 10050) + privateRelays, hasPrivateRelays, err := CheckPrivateRelays(ctx, pubkey, relayConfig) + if err != nil { + // Continue with regular flow if private relay check fails + hasPrivateRelays = false + } + + var dmEvent *nostr.Event + var targetRelays []string + + if hasPrivateRelays && len(privateRelays) > 0 { + log.Printf("Using NIP-17 DM for user with private relays") + // Use NIP-17 DMs for users with private relays + dmEvent, err = CreateNIP17DM(pubkey, config.PrivateKey, account, code, serverName) + if err != nil { + return fmt.Errorf("failed to create NIP-17 DM: %w", err) + } + targetRelays = privateRelays + log.Printf("Targeting private relays: %v", targetRelays) + } else { + log.Printf("Using NIP-04 DM for regular user") + // Use NIP-04 DMs for regular users + dmEvent, err = CreateNIP04DM(pubkey, config.PrivateKey, account, code, serverName) + if err != nil { + return fmt.Errorf("failed to create NIP-04 DM: %w", err) + } + + // Discover inbox relays for NIP-04 + inboxRelays, err := DiscoverInboxRelays(pubkey, relayConfig) + if err != nil { + return fmt.Errorf("failed to discover inbox relays: %w", err) + } + targetRelays = inboxRelays + log.Printf("Targeting inbox relays: %v", targetRelays) + } + + // Send to target relays with retry logic + var lastErr error + successCount := 0 + + for _, relayURL := range targetRelays { + // Try connecting and sending + err := sendToRelayWithRetry(ctx, relayURL, *dmEvent, config.PrivateKey) + if err != nil { + lastErr = err + continue + } + + successCount++ + } + + if successCount == 0 { + if lastErr != nil { + return fmt.Errorf("%w: %v", ErrDMSendFailed, lastErr) + } + return ErrDMSendFailed + } + + return nil +} + +// sendToRelayWithRetry attempts to send a DM to a relay with retry logic for auth failures +func sendToRelayWithRetry(ctx context.Context, relayURL string, event nostr.Event, privkey string) error { + // Create a separate timeout context for this relay connection (15 seconds) + relayCtx, cancel := context.WithTimeout(context.Background(), 15*time.Second) + defer cancel() + + // First attempt without auth + relay, err := nostr.RelayConnect(relayCtx, relayURL) + if err != nil { + return fmt.Errorf("failed to connect to relay %s: %w", relayURL, err) + } + defer relay.Close() + + // Try sending without auth first + err = relay.Publish(relayCtx, event) + if err == nil { + return nil // Success! + } + + // If we get an auth error, try with authentication + if strings.Contains(err.Error(), "auth-required") || strings.Contains(err.Error(), "you must auth") { + // Close and reconnect with auth + relay.Close() + + // Create a new timeout context for the auth connection + authCtx, authCancel := context.WithTimeout(context.Background(), 15*time.Second) + defer authCancel() + + relay, err = ConnectToRelay(authCtx, relayURL, privkey) + if err != nil { + return fmt.Errorf("failed to connect with auth to relay %s: %w", relayURL, err) + } + defer relay.Close() + + // Try sending again after auth + err = relay.Publish(authCtx, event) + if err != nil { + return fmt.Errorf("failed to publish to authenticated relay %s: %w", relayURL, err) + } + + return nil + } + + // Other error, return as-is + return fmt.Errorf("failed to publish to relay %s: %w", relayURL, err) +} + +// SendNIP04DM sends a NIP-04 DM to specific relays +func SendNIP04DM(ctx context.Context, event *nostr.Event, relays []string, privkey string) error { + var lastErr error + successCount := 0 + + for _, relayURL := range relays { + // Try connecting and sending + err := sendToRelayWithRetry(ctx, relayURL, *event, privkey) + if err != nil { + lastErr = err + continue + } + + successCount++ + } + + if successCount == 0 { + if lastErr != nil { + return fmt.Errorf("%w: %v", ErrDMSendFailed, lastErr) + } + return ErrDMSendFailed + } + + return nil +} + +// SendNIP17DM sends a NIP-17 DM to private relays +func SendNIP17DM(ctx context.Context, event *nostr.Event, privateRelays []string, privkey string) error { + var lastErr error + successCount := 0 + + for _, relayURL := range privateRelays { + // Try connecting and sending + err := sendToRelayWithRetry(ctx, relayURL, *event, privkey) + if err != nil { + lastErr = err + continue + } + + successCount++ + } + + if successCount == 0 { + if lastErr != nil { + return fmt.Errorf("%w: %v", ErrDMSendFailed, lastErr) + } + return ErrDMSendFailed + } + + return nil +} diff --git a/irc/nostr/errors.go b/irc/nostr/errors.go new file mode 100644 index 00000000..c84b9aa7 --- /dev/null +++ b/irc/nostr/errors.go @@ -0,0 +1,37 @@ +// Copyright (c) 2024 Ergo Contributors +// released under the MIT license + +package nostr + +import "errors" + +var ( + // Identifier validation errors + ErrInvalidNostrIdentifier = errors.New("invalid nostr identifier format") + ErrInvalidPubkeyFormat = errors.New("invalid pubkey format") + ErrInvalidPubkeyLength = errors.New("invalid pubkey length") + ErrInvalidHexFormat = errors.New("invalid hex format") + ErrInvalidPrivkeyLength = errors.New("invalid private key length") + ErrInvalidNpubPrefix = errors.New("invalid npub prefix") + + // NIP-05 resolution errors + ErrNIP05ResolutionFailed = errors.New("NIP-05 resolution failed") + ErrNIP05NotFound = errors.New("NIP-05 address not found") + ErrNIP05InvalidResponse = errors.New("invalid NIP-05 response") + ErrNIP05HTTPError = errors.New("HTTP error during NIP-05 resolution") + ErrNIP05PubkeyNotFound = errors.New("pubkey not found in NIP-05 response") + + // Relay discovery errors + ErrRelayDiscoveryFailed = errors.New("relay discovery failed") + ErrNoInboxRelaysFound = errors.New("no inbox relays found") + ErrRelayConnectionFailed = errors.New("relay connection failed") + ErrRelayAuthFailed = errors.New("relay authentication failed") + + // DM sending errors + ErrDMSendFailed = errors.New("DM send failed") + ErrDMEncryptionFailed = errors.New("DM encryption failed") + ErrNostrKeyNotConfigured = errors.New("nostr private key not configured") + + // Decoding errors + ErrNpubDecodingFailed = errors.New("npub decoding failed") +) diff --git a/irc/nostr/nip05.go b/irc/nostr/nip05.go new file mode 100644 index 00000000..8fc3add9 --- /dev/null +++ b/irc/nostr/nip05.go @@ -0,0 +1,115 @@ +// Copyright (c) 2024 Ergo Contributors +// released under the MIT license + +package nostr + +import ( + "encoding/json" + "fmt" + "net/http" + "strings" + "time" +) + +// NIP05Response represents the JSON response from a .well-known/nostr.json endpoint +type NIP05Response struct { + Names map[string]string `json:"names"` + Relays map[string][]string `json:"relays,omitempty"` +} + +// NIP05Config holds configuration for NIP-05 resolution +type NIP05Config struct { + Timeout time.Duration + UserAgent string +} + +// ResolveNIP05 resolves a NIP-05 identifier to a pubkey +func ResolveNIP05(identifier string, config NIP05Config) (pubkey string, relays []string, err error) { + if !IsNIP05(identifier) { + return "", nil, ErrInvalidPubkeyFormat + } + + parts := strings.Split(identifier, "@") + if len(parts) != 2 { + return "", nil, ErrInvalidPubkeyFormat + } + + name, domain := parts[0], parts[1] + + // Construct the well-known URL + url := fmt.Sprintf("https://%s/.well-known/nostr.json?name=%s", domain, name) + + // Create HTTP client with timeout + client := &http.Client{ + Timeout: config.Timeout, + } + + // Make the request + req, err := http.NewRequest("GET", url, nil) + if err != nil { + return "", nil, fmt.Errorf("%w: %v", ErrNIP05HTTPError, err) + } + + if config.UserAgent != "" { + req.Header.Set("User-Agent", config.UserAgent) + } + + resp, err := client.Do(req) + if err != nil { + return "", nil, fmt.Errorf("%w: %v", ErrNIP05HTTPError, err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return "", nil, fmt.Errorf("%w: HTTP %d", ErrNIP05HTTPError, resp.StatusCode) + } + + // Parse the JSON response + var nip05Resp NIP05Response + if err := json.NewDecoder(resp.Body).Decode(&nip05Resp); err != nil { + return "", nil, fmt.Errorf("%w: %v", ErrNIP05InvalidResponse, err) + } + + // Look up the pubkey for this name + pubkey, exists := nip05Resp.Names[name] + if !exists { + return "", nil, ErrNIP05PubkeyNotFound + } + + // Validate the returned pubkey + if err := ValidateHexPubkey(pubkey); err != nil { + return "", nil, fmt.Errorf("%w: invalid pubkey in response", ErrNIP05InvalidResponse) + } + + // Get relays if available + if nip05Resp.Relays != nil { + relays = nip05Resp.Relays[pubkey] + } + + return pubkey, relays, nil +} + +// ResolvePubkey resolves any nostr identifier to a hex pubkey +func ResolvePubkey(identifier string, config NIP05Config) (pubkey string, relays []string, err error) { + // Debug logging to see what identifier we're trying to resolve + fmt.Printf("[DEBUG] ResolvePubkey called with identifier: '%s'\n", identifier) + fmt.Printf("[DEBUG] IsNIP05: %v, IsPubkey: %v, IsNpub: %v, IsHexPubkey: %v\n", + IsNIP05(identifier), IsPubkey(identifier), IsNpub(identifier), IsHexPubkey(identifier)) + + if IsNIP05(identifier) { + fmt.Printf("[DEBUG] Resolving as NIP-05 identifier\n") + return ResolveNIP05(identifier, config) + } else if IsPubkey(identifier) { + fmt.Printf("[DEBUG] Resolving as pubkey, normalizing...\n") + normalizedPubkey, err := NormalizePubkey(identifier) + if err != nil { + fmt.Printf("[DEBUG] NormalizePubkey failed: %v\n", err) + return "", nil, err + } + fmt.Printf("[DEBUG] Normalized pubkey: %s\n", normalizedPubkey) + return normalizedPubkey, nil, nil + } + + fmt.Printf("[DEBUG] Identifier doesn't match any known format\n") + return "", nil, ErrInvalidPubkeyFormat +} diff --git a/irc/nostr/nostr.go b/irc/nostr/nostr.go new file mode 100644 index 00000000..f9c394f6 --- /dev/null +++ b/irc/nostr/nostr.go @@ -0,0 +1,160 @@ +// Copyright (c) 2024 Ergo Contributors +// released under the MIT license + +package nostr + +import ( + "encoding/hex" + "fmt" + "regexp" + "strings" + + "github.com/nbd-wtf/go-nostr" + "github.com/nbd-wtf/go-nostr/nip19" +) + +var ( + // NIP-05 identifier format: name@domain.tld + nip05Regex = regexp.MustCompile(`^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`) + + // npub format (bech32 encoded pubkey) + npubRegex = regexp.MustCompile(`^npub1[a-zA-Z0-9]{58}$`) + + // hex pubkey format (64 hex characters) + hexPubkeyRegex = regexp.MustCompile(`^[a-fA-F0-9]{64}$`) +) + +// IsNostrIdentifier checks if a string could be a nostr identifier (NIP-05 or pubkey) +func IsNostrIdentifier(identifier string) bool { + return IsNIP05(identifier) || IsPubkey(identifier) +} + +// IsValidNostrIdentifier validates a nostr identifier format +func IsValidNostrIdentifier(identifier string) bool { + return IsNostrIdentifier(identifier) +} + +// IsNIP05 checks if the identifier is a NIP-05 address +func IsNIP05(identifier string) bool { + return nip05Regex.MatchString(identifier) +} + +// IsPubkey checks if the identifier is a pubkey (npub or hex) +func IsPubkey(identifier string) bool { + return IsNpub(identifier) || IsHexPubkey(identifier) +} + +// IsNpub checks if the identifier is an npub (bech32) format +func IsNpub(identifier string) bool { + return npubRegex.MatchString(identifier) +} + +// IsHexPubkey checks if the identifier is a hex pubkey +func IsHexPubkey(identifier string) bool { + return hexPubkeyRegex.MatchString(identifier) +} + +// NormalizePubkey converts npub to hex format, returns hex pubkey as-is +func NormalizePubkey(pubkey string) (string, error) { + fmt.Printf("[DEBUG] NormalizePubkey called with: '%s' (len=%d)\n", pubkey, len(pubkey)) + fmt.Printf("[DEBUG] IsHexPubkey: %v, IsNpub: %v\n", IsHexPubkey(pubkey), IsNpub(pubkey)) + + if IsHexPubkey(pubkey) { + fmt.Printf("[DEBUG] Treating as hex pubkey\n") + return strings.ToLower(pubkey), nil + } + + if IsNpub(pubkey) { + fmt.Printf("[DEBUG] Treating as npub, decoding...\n") + // Use go-nostr to decode npub + prefix, data, err := nip19.Decode(pubkey) + if err != nil { + fmt.Printf("[DEBUG] nip19.Decode failed: %v\n", err) + return "", ErrInvalidPubkeyFormat + } + fmt.Printf("[DEBUG] nip19.Decode success - prefix: %s, data type: %T\n", prefix, data) + + // Handle both string and []byte return types from nip19.Decode + switch v := data.(type) { + case []byte: + if len(v) == 32 { + hexResult := hex.EncodeToString(v) + fmt.Printf("[DEBUG] Successfully converted npub bytes to hex: %s\n", hexResult) + return hexResult, nil + } + case string: + if len(v) == 64 { + // Already a hex string, validate it + if err := ValidateHexPubkey(v); err != nil { + fmt.Printf("[DEBUG] Invalid hex pubkey from npub: %v\n", err) + return "", ErrInvalidPubkeyFormat + } + fmt.Printf("[DEBUG] Successfully got hex string from npub: %s\n", v) + return strings.ToLower(v), nil + } + } + + fmt.Printf("[DEBUG] Unexpected data format from nip19.Decode: %T, value: %v\n", data, data) + return "", ErrInvalidPubkeyFormat + } + + fmt.Printf("[DEBUG] Pubkey doesn't match hex or npub format\n") + return "", ErrInvalidPubkeyFormat +} + +// ValidateHexPubkey ensures a hex string is a valid pubkey +func ValidateHexPubkey(hexStr string) error { + if len(hexStr) != 64 { + return ErrInvalidPubkeyLength + } + + _, err := hex.DecodeString(hexStr) + if err != nil { + return ErrInvalidHexFormat + } + + return nil +} + +// ValidatePrivateKey validates a hex private key +func ValidatePrivateKey(privkeyHex string) error { + if len(privkeyHex) != 64 { + return ErrInvalidPubkeyLength + } + + _, err := hex.DecodeString(privkeyHex) + if err != nil { + return ErrInvalidHexFormat + } + + return nil +} + +// GetPubkeyFromPrivkey derives public key from private key using go-nostr +func GetPubkeyFromPrivkey(privkeyHex string) (string, error) { + if len(privkeyHex) != 64 { + return "", ErrInvalidPrivkeyLength + } + + pubkey, err := nostr.GetPublicKey(privkeyHex) + if err != nil { + return "", err + } + + return pubkey, nil +} + +// HexToNpub converts a hex pubkey to npub format +func HexToNpub(hexPubkey string) (string, error) { + if !IsHexPubkey(hexPubkey) { + return "", ErrInvalidPubkeyFormat + } + + // Encode as npub using nip19 (it expects hex string, not bytes) + npub, err := nip19.EncodePublicKey(hexPubkey) + if err != nil { + return "", err + } + + return npub, nil +} diff --git a/irc/nostr/relay.go b/irc/nostr/relay.go new file mode 100644 index 00000000..3bfc9db9 --- /dev/null +++ b/irc/nostr/relay.go @@ -0,0 +1,271 @@ +// Copyright (c) 2024 Ergo Contributors +// released under the MIT license + +package nostr + +import ( + "context" + "encoding/json" + "fmt" + "log" + "net/http" + "strings" + "time" + + "github.com/nbd-wtf/go-nostr" +) + +// RelayConfig holds configuration for relay operations +type RelayConfig struct { + DefaultRelays []string + Timeout time.Duration + MaxRelays int +} + +// RelayInfo represents the NIP-11 relay information document +type RelayInfo struct { + Name string `json:"name"` + Description string `json:"description"` + PubKey string `json:"pubkey"` + Contact string `json:"contact"` + Limitation struct { + AuthRequired bool `json:"auth_required"` + } `json:"limitation"` +} + +// DiscoverInboxRelays discovers a user's inbox relays using NIP-65 +func DiscoverInboxRelays(pubkey string, config RelayConfig) ([]string, error) { + ctx, cancel := context.WithTimeout(context.Background(), config.Timeout) + defer cancel() + + // Try to get relays from NIP-65 (kind 10002 events) + inboxRelays, err := queryRelayListMetadata(ctx, pubkey, config) + if err == nil && len(inboxRelays) > 0 { + return inboxRelays, nil + } + + // Fallback to default relays if no inbox relays found + if len(config.DefaultRelays) > 0 { + return config.DefaultRelays, nil + } + + return nil, ErrNoInboxRelaysFound +} + +// queryRelayListMetadata queries for NIP-65 relay list metadata events +func queryRelayListMetadata(ctx context.Context, pubkey string, config RelayConfig) ([]string, error) { + var inboxRelays []string + + // Connect to default relays to query for relay list metadata + for _, relayURL := range config.DefaultRelays { + relay, err := nostr.RelayConnect(ctx, relayURL) + if err != nil { + continue // Try next relay + } + + // Query for kind 10002 events (NIP-65 relay list metadata) + filters := []nostr.Filter{{ + Authors: []string{pubkey}, + Kinds: []int{10002}, + Limit: 1, + }} + + sub, err := relay.Subscribe(ctx, filters) + if err != nil { + relay.Close() + continue + } + + // Wait for events with timeout + done := false + select { + case event := <-sub.Events: + relays := parseRelayListEvent(*event) + inboxRelays = append(inboxRelays, relays...) + case <-time.After(5 * time.Second): + // Timeout waiting for event + case <-ctx.Done(): + done = true + } + + sub.Unsub() + relay.Close() + + if done { + break + } + + if len(inboxRelays) > 0 { + break // Found relays, no need to query more + } + } + + if len(inboxRelays) == 0 { + return nil, ErrRelayDiscoveryFailed + } + + return inboxRelays, nil +} + +// parseRelayListEvent parses a NIP-65 relay list metadata event +func parseRelayListEvent(event nostr.Event) []string { + var inboxRelays []string + + for _, tag := range event.Tags { + if len(tag) >= 2 && tag[0] == "r" { + relayURL := tag[1] + + // Check if this is an inbox relay (read capability) + // If no marker is specified, assume both read and write + isInbox := true + if len(tag) >= 3 { + marker := tag[2] + isInbox = marker == "read" || marker == "" + } + + if isInbox { + inboxRelays = append(inboxRelays, relayURL) + } + } + } + + return inboxRelays +} + +// checkRelayRequiresAuth checks if a relay requires authentication via NIP-11 +func checkRelayRequiresAuth(url string) bool { + httpURL := strings.Replace(strings.Replace(url, "ws://", "http://", 1), "wss://", "https://", 1) + + client := &http.Client{ + Timeout: time.Second * 5, + } + + req, err := http.NewRequest("GET", httpURL, nil) + if err != nil { + return false + } + + req.Header.Set("Accept", "application/nostr+json") + + resp, err := client.Do(req) + if err != nil { + return false + } + defer resp.Body.Close() + + var info RelayInfo + if err := json.NewDecoder(resp.Body).Decode(&info); err != nil { + return false + } + + return info.Limitation.AuthRequired +} + +// ConnectToRelay establishes a connection to a nostr relay with optional NIP-42 auth +func ConnectToRelay(ctx context.Context, url string, privkey string) (*nostr.Relay, error) { + log.Printf("Connecting to relay: %s\n", url) + + relay, err := nostr.RelayConnect(ctx, url) + if err != nil { + log.Printf("Failed to connect to relay: %s, error: %v\n", url, err) + return nil, fmt.Errorf("%w: %v", ErrRelayConnectionFailed, err) + } + + log.Printf("Connected to relay: %s\n", url) + + // Check if relay requires auth before attempting authentication + if privkey != "" && checkRelayRequiresAuth(url) { + log.Printf("Relay requires authentication: %s\n", url) + + err = relay.Auth(ctx, func(authEvent *nostr.Event) error { + // Validate challenge tag is present and not empty + challengeTag := authEvent.Tags.Find("challenge") + if len(challengeTag) < 2 || challengeTag[1] == "" || challengeTag[1] == " " { + return fmt.Errorf("invalid or missing challenge in auth event") + } + return authEvent.Sign(privkey) + }) + if err != nil { + log.Printf("Failed to authenticate with relay: %s, error: %v\n", url, err) + // Don't fail connection on auth error - some operations might still work + // The relay will reject operations that require auth if needed + } else { + log.Printf("Authenticated with relay: %s\n", url) + } + } + + return relay, nil +} + +// SendEventToRelay sends a nostr event to a relay +func SendEventToRelay(ctx context.Context, relay *nostr.Relay, event nostr.Event) error { + err := relay.Publish(ctx, event) + if err != nil { + return fmt.Errorf("%w: %v", ErrDMSendFailed, err) + } + + return nil +} + +// CheckPrivateRelays checks if a user has private relays (NIP-50 kind 10050) +func CheckPrivateRelays(ctx context.Context, pubkey string, config RelayConfig) ([]string, bool, error) { + var privateRelays []string + + // Connect to default relays to query for private relay list + for _, relayURL := range config.DefaultRelays { + relay, err := nostr.RelayConnect(ctx, relayURL) + if err != nil { + continue + } + + // Query for kind 10050 events (private relay list) + filters := []nostr.Filter{{ + Authors: []string{pubkey}, + Kinds: []int{10050}, + Limit: 1, + }} + + sub, err := relay.Subscribe(ctx, filters) + if err != nil { + relay.Close() + continue + } + + // Wait for events + done := false + select { + case event := <-sub.Events: + privateRelays = parsePrivateRelayList(*event) + case <-time.After(5 * time.Second): + // Timeout + case <-ctx.Done(): + done = true + } + + sub.Unsub() + relay.Close() + + if done { + break + } + + if len(privateRelays) > 0 { + return privateRelays, true, nil + } + } + + return nil, false, nil +} + +// parsePrivateRelayList parses a NIP-50 private relay list event +func parsePrivateRelayList(event nostr.Event) []string { + var privateRelays []string + + for _, tag := range event.Tags { + if len(tag) >= 2 && tag[0] == "relay" { + privateRelays = append(privateRelays, tag[1]) + } + } + + return privateRelays +} diff --git a/languages/example/help.lang.json b/languages/example/help.lang.json index 259f2138..d4e9d9a5 100644 --- a/languages/example/help.lang.json +++ b/languages/example/help.lang.json @@ -43,7 +43,7 @@ "PONG ...\n\nReplies to a PING. Used to check link connectivity.": "PONG ...\n\nReplies to a PING. Used to check link connectivity.", "PRIVMSG {,} \n\nSends the text to the given targets as a PRIVMSG.": "PRIVMSG {,} \n\nSends the text to the given targets as a PRIVMSG.", "QUIT [reason]\n\nIndicates that you're leaving the server, and shows everyone the given reason.": "QUIT [reason]\n\nIndicates that you're leaving the server, and shows everyone the given reason.", - "REGISTER \n\nRegisters an account in accordance with the draft/register capability.": "REGISTER \n\nRegisters an account in accordance with the draft/register capability.", + "REGISTER \n\nRegisters an account using nostr verification. The nostr-identifier can be:\n• NIP-05 address: alice@example.com\n• npub key: npub1abc123def456...\n• hex pubkey: 3bf0c63fcb93c5ef2f068d70b8d70d963b649d75...\n\nUse * if you want to register without nostr verification.": "REGISTER \n\nRegisters an account using nostr verification. The nostr-identifier can be:\n• NIP-05 address: alice@example.com\n• npub key: npub1abc123def456...\n• hex pubkey: 3bf0c63fcb93c5ef2f068d70b8d70d963b649d75...\n\nUse * if you want to register without nostr verification.", "REHASH\n\nReloads the config file and updates TLS certificates on listeners": "REHASH\n\nReloads the config file and updates TLS certificates on listeners", "RELAYMSG :\n\nThis command lets channel operators relay messages to their\nchannel from other messaging systems using relay bots. The\nspoofed nickname MUST contain a forwardslash.\n\nFor example:\n\tRELAYMSG #ircv3 Mallory/D :Welp, we linked Discord...": "RELAYMSG :\n\nThis command lets channel operators relay messages to their\nchannel from other messaging systems using relay bots. The\nspoofed nickname MUST contain a forwardslash.\n\nFor example:\n\tRELAYMSG #ircv3 Mallory/D :Welp, we linked Discord...", "RENAME []\n\nRenames the given channel with the given reason, if possible.\n\nFor example:\n\tRENAME #ircv2 #ircv3 :Protocol upgrades!": "RENAME []\n\nRenames the given channel with the given reason, if possible.\n\nFor example:\n\tRENAME #ircv2 #ircv3 :Protocol upgrades!", @@ -64,7 +64,7 @@ "USER 0 * \n\nUsed in connection registration, sets your username and realname to the given\nvalues (though your username may also be looked up with Ident).": "USER 0 * \n\nUsed in connection registration, sets your username and realname to the given\nvalues (though your username may also be looked up with Ident).", "USERHOST { }\n\t\t\nShows information about the given users. Takes up to 10 nicknames.": "USERHOST { }\n\t\t\nShows information about the given users. Takes up to 10 nicknames.", "USERS [parameters]\n\nThe USERS command is not implemented.": "USERS [parameters]\n\nThe USERS command is not implemented.", - "VERIFY \n\nVerifies an account in accordance with the draft/register capability.": "VERIFY \n\nVerifies an account in accordance with the draft/register capability.", + "VERIFY \n\nVerifies an account using the verification code sent via nostr DM.": "VERIFY \n\nVerifies an account using the verification code sent via nostr DM.", "VERSION [server]\n\nViews the version of software and the RPL_ISUPPORT tokens for the given server.": "VERSION [server]\n\nViews the version of software and the RPL_ISUPPORT tokens for the given server.", "WEBIRC [:]\n\nUsed by web<->IRC gateways and bouncers, the WEBIRC command allows gateways to\npass-through the real IP addresses of clients:\nircv3.net/specs/extensions/webirc.html\n\n is a list of space-separated strings indicating various details about\nthe connection from the client to the gateway, such as:\n\n- tls: this flag indicates that the client->gateway connection is secure": "WEBIRC [:]\n\nUsed by web<->IRC gateways and bouncers, the WEBIRC command allows gateways to\npass-through the real IP addresses of clients:\nircv3.net/specs/extensions/webirc.html\n\n is a list of space-separated strings indicating various details about\nthe connection from the client to the gateway, such as:\n\n- tls: this flag indicates that the client->gateway connection is secure", "WHO [o]\n\nReturns information for the given user.": "WHO [o]\n\nReturns information for the given user.", diff --git a/languages/example/nickserv.lang.json b/languages/example/nickserv.lang.json index 2023b1cf..0dfab6eb 100644 --- a/languages/example/nickserv.lang.json +++ b/languages/example/nickserv.lang.json @@ -7,7 +7,7 @@ "$bCLIENTS$b can list and logout the sessions attached to a nickname.": "$bCLIENTS$b can list and logout the sessions attached to a nickname.", "$bDM-HISTORY$b\n'dm-history' is only effective for always-on clients. It lets you control\nhow the history of your direct messages is stored. Your options are:\n1. 'off' [no history]\n2. 'ephemeral' [a limited amount of temporary history, not stored on disk]\n3. 'on' [history stored in a permanent database, if available]\n4. 'default' [use the server default]": "$bDM-HISTORY$b\n'dm-history' is only effective for always-on clients. It lets you control\nhow the history of your direct messages is stored. Your options are:\n1. 'off' [no history]\n2. 'ephemeral' [a limited amount of temporary history, not stored on disk]\n3. 'on' [history stored in a permanent database, if available]\n4. 'default' [use the server default]", "$bDROP$b de-links your current (or the given) nickname from your user account.": "$bDROP$b de-links your current (or the given) nickname from your user account.", - "$bEMAIL$b\n'email' controls the e-mail address associated with your account (if the\nserver operator allows it, this address can be used for password resets).\nAs an additional security measure, if you have a password set, you must\nprovide it as an additional argument to $bSET$b, for example,\nSET EMAIL test@example.com hunter2": "$bEMAIL$b\n'email' controls the e-mail address associated with your account (if the\nserver operator allows it, this address can be used for password resets).\nAs an additional security measure, if you have a password set, you must\nprovide it as an additional argument to $bSET$b, for example,\nSET EMAIL test@example.com hunter2", + "$bNOSTR$b\n'nostr' controls the nostr identifier associated with your account.\nThis can be a NIP-05 address, npub key, or hex pubkey. As an additional\nsecurity measure, if you have a password set, you must provide it as an\nadditional argument to $bSET$b, for example,\nSET NOSTR alice@example.com hunter2": "$bNOSTR$b\n'nostr' controls the nostr identifier associated with your account.\nThis can be a NIP-05 address, npub key, or hex pubkey. As an additional\nsecurity measure, if you have a password set, you must provide it as an\nadditional argument to $bSET$b, for example,\nSET NOSTR alice@example.com hunter2", "$bENFORCE$b\n'enforce' lets you specify a custom enforcement mechanism for your registered\nnicknames. Your options are:\n1. 'none' [no enforcement, overriding the server default]\n2. 'strict' [you must already be authenticated to use the nick]\n3. 'default' [use the server default]": "$bENFORCE$b\n'enforce' lets you specify a custom enforcement mechanism for your registered\nnicknames. Your options are:\n1. 'none' [no enforcement, overriding the server default]\n2. 'strict' [you must already be authenticated to use the nick]\n3. 'default' [use the server default]", "$bERASE$b erases all records of an account, allowing reuse.": "$bERASE$b erases all records of an account, allowing reuse.", "$bGET$b queries the current values of your account settings": "$bGET$b queries the current values of your account settings", @@ -18,15 +18,15 @@ "$bLIST$b searches the list of registered nicknames.": "$bLIST$b searches the list of registered nicknames.", "$bMULTICLIENT$b\nIf 'multiclient' is enabled and you are already logged in and using a nick, a\nsecond client of yours that authenticates with SASL and requests the same nick\nis allowed to attach to the nick as well (this is comparable to the behavior\nof IRC \"bouncers\" like ZNC). Your options are 'on' (allow this behavior),\n'off' (disallow it), and 'default' (use the server default value).": "$bMULTICLIENT$b\nIf 'multiclient' is enabled and you are already logged in and using a nick, a\nsecond client of yours that authenticates with SASL and requests the same nick\nis allowed to attach to the nick as well (this is comparable to the behavior\nof IRC \"bouncers\" like ZNC). Your options are 'on' (allow this behavior),\n'off' (disallow it), and 'default' (use the server default value).", "$bPASSWD$b lets you change your password.": "$bPASSWD$b lets you change your password.", - "$bREGISTER$b lets you register a user account.": "$bREGISTER$b lets you register a user account.", + "$bREGISTER$b lets you register a user account.": "$bREGISTER$b lets you register a user account with nostr verification.", "$bRENAME$b renames an account": "$bRENAME$b renames an account", "$bREPLAY-JOINS$b\n'replay-joins' controls whether replayed channel history will include\nlines for join and part. This provides more information about the context of\nmessages, but may be spammy. Your options are 'always' and the default of\n'commands-only' (the messages will be replayed in CHATHISTORY output, but not\nduring autoreplay).": "$bREPLAY-JOINS$b\n'replay-joins' controls whether replayed channel history will include\nlines for join and part. This provides more information about the context of\nmessages, but may be spammy. Your options are 'always' and the default of\n'commands-only' (the messages will be replayed in CHATHISTORY output, but not\nduring autoreplay).", - "$bRESETPASS$b completes an email-based password reset": "$bRESETPASS$b completes an email-based password reset", + "$bRESETPASS$b completes a nostr-based password reset": "$bRESETPASS$b completes a nostr-based password reset", "$bSADROP$b forcibly de-links the given nickname from its user account.": "$bSADROP$b forcibly de-links the given nickname from its user account.", "$bSAGET$b queries the current values of another user's account settings": "$bSAGET$b queries the current values of another user's account settings", "$bSAREGISTER$b registers an account on someone else's behalf.": "$bSAREGISTER$b registers an account on someone else's behalf.", "$bSASET$b modifies another user's account settings": "$bSASET$b modifies another user's account settings", - "$bSENDPASS$b initiates an email-based password reset": "$bSENDPASS$b initiates an email-based password reset", + "$bSENDPASS$b initiates a nostr-based password reset": "$bSENDPASS$b initiates a nostr-based password reset", "$bSET$b modifies your account settings": "$bSET$b modifies your account settings", "$bSUSPEND$b manages account suspensions": "$bSUSPEND$b manages account suspensions", "$bUNREGISTER$b lets you delete your user account.": "$bUNREGISTER$b lets you delete your user account.", @@ -39,7 +39,7 @@ "Password incorrect": "Password incorrect", "Passwords do not match": "Passwords do not match", "Successfully reset account password": "Successfully reset account password", - "Successfully sent password reset email": "Successfully sent password reset email", + "Successfully sent password reset via nostr DM": "Successfully sent password reset via nostr DM", "Syntax $bSET $b\n\nSET modifies your account settings. The following settings are available:": "Syntax $bSET $b\n\nSET modifies your account settings. The following settings are available:", "Syntax: $bCERT [account] [certfp]$b\n\nCERT examines or modifies the SHA-256 TLS certificate fingerprints that can\nbe used to log into an account. Specifically, $bCERT LIST$b lists the\nauthorized fingerprints, $bCERT ADD $b adds a new fingerprint, and\n$bCERT DEL $b removes a fingerprint. If you're an IRC operator\nwith the correct permissions, you can act on another user's account, for\nexample with $bCERT ADD $b. See the operator manual\nfor instructions on how to compute the fingerprint.": "Syntax: $bCERT [account] [certfp]$b\n\nCERT examines or modifies the SHA-256 TLS certificate fingerprints that can\nbe used to log into an account. Specifically, $bCERT LIST$b lists the\nauthorized fingerprints, $bCERT ADD $b adds a new fingerprint, and\n$bCERT DEL $b removes a fingerprint. If you're an IRC operator\nwith the correct permissions, you can act on another user's account, for\nexample with $bCERT ADD $b. See the operator manual\nfor instructions on how to compute the fingerprint.", "Syntax: $bCLIENTS LIST [nickname]$b\n\nCLIENTS LIST shows information about the clients currently attached, via\nthe server's multiclient functionality, to your nickname. An administrator\ncan use this command to list another user's clients.\n\nSyntax: $bCLIENTS LOGOUT [nickname] [client_id/all]$b\n\nCLIENTS LOGOUT detaches a single client, or all clients currently attached\nto your nickname. An administrator can use this command to logout another\nuser's clients.": "Syntax: $bCLIENTS LIST [nickname]$b\n\nCLIENTS LIST shows information about the clients currently attached, via\nthe server's multiclient functionality, to your nickname. An administrator\ncan use this command to list another user's clients.\n\nSyntax: $bCLIENTS LOGOUT [nickname] [client_id/all]$b\n\nCLIENTS LOGOUT detaches a single client, or all clients currently attached\nto your nickname. An administrator can use this command to logout another\nuser's clients.", @@ -53,19 +53,19 @@ "Syntax: $bINFO [username]$b\n\nINFO gives you information about the given (or your own) user account.": "Syntax: $bINFO [username]$b\n\nINFO gives you information about the given (or your own) user account.", "Syntax: $bLIST [regex]$b\n\nLIST returns the list of registered nicknames, which match the given regex.\nIf no regex is provided, all registered nicknames are returned.": "Syntax: $bLIST [regex]$b\n\nLIST returns the list of registered nicknames, which match the given regex.\nIf no regex is provided, all registered nicknames are returned.", "Syntax: $bPASSWD $b\nOr: $bPASSWD $b\n\nPASSWD lets you change your account password. You must supply your current\npassword and confirm the new one by typing it twice. If you're an IRC operator\nwith the correct permissions, you can use PASSWD to reset someone else's\npassword by supplying their username and then the desired password. To\nindicate an empty password, use * instead.": "Syntax: $bPASSWD $b\nOr: $bPASSWD $b\n\nPASSWD lets you change your account password. You must supply your current\npassword and confirm the new one by typing it twice. If you're an IRC operator\nwith the correct permissions, you can use PASSWD to reset someone else's\npassword by supplying their username and then the desired password. To\nindicate an empty password, use * instead.", - "Syntax: $bREGISTER [email]$b\n\nREGISTER lets you register your current nickname as a user account. If the\nserver allows anonymous registration, you can omit the e-mail address.\n\nIf you are currently logged in with a TLS client certificate and wish to use\nit instead of a password to log in, send * as the password.": "Syntax: $bREGISTER [email]$b\n\nREGISTER lets you register your current nickname as a user account. If the\nserver allows anonymous registration, you can omit the e-mail address.\n\nIf you are currently logged in with a TLS client certificate and wish to use\nit instead of a password to log in, send * as the password.", + "Syntax: $bREGISTER [nostr-identifier]$b\n\nREGISTER lets you register your current nickname as a user account using nostr\nverification. You can provide a nostr identifier in one of these formats:\n\n• NIP-05 address: alice@example.com\n• npub key: npub1abc123def456...\n• hex pubkey: 3bf0c63fcb93c5ef2f068d70b8d70d963b649d75...\n\nIf the server allows anonymous registration, you can omit the nostr identifier.\nIf you are currently logged in with a TLS client certificate and wish to use\nit instead of a password to log in, send * as the password.": "Syntax: $bREGISTER [nostr-identifier]$b\n\nREGISTER lets you register your current nickname as a user account using nostr\nverification. You can provide a nostr identifier in one of these formats:\n\n• NIP-05 address: alice@example.com\n• npub key: npub1abc123def456...\n• hex pubkey: 3bf0c63fcb93c5ef2f068d70b8d70d963b649d75...\n\nIf the server allows anonymous registration, you can omit the nostr identifier.\nIf you are currently logged in with a TLS client certificate and wish to use\nit instead of a password to log in, send * as the password.", "Syntax: $bRENAME $b\n\nRENAME allows a server administrator to change the name of an account.\nCurrently, you can only change the canonical casefolding of an account\n(e.g., you can change \"Alice\" to \"alice\", but not \"Alice\" to \"Amanda\").": "Syntax: $bRENAME $b\n\nRENAME allows a server administrator to change the name of an account.\nCurrently, you can only change the canonical casefolding of an account\n(e.g., you can change \"Alice\" to \"alice\", but not \"Alice\" to \"Amanda\").", - "Syntax: $bRESETPASS $b\n\nRESETPASS resets an account password, using a reset code that was emailed as\nthe result of a previous $bSENDPASS$b command.": "Syntax: $bRESETPASS $b\n\nRESETPASS resets an account password, using a reset code that was emailed as\nthe result of a previous $bSENDPASS$b command.", + "Syntax: $bRESETPASS $b\n\nRESETPASS resets an account password, using a reset code that was sent via\nnostr DM as the result of a previous $bSENDPASS$b command.": "Syntax: $bRESETPASS $b\n\nRESETPASS resets an account password, using a reset code that was sent via\nnostr DM as the result of a previous $bSENDPASS$b command.", "Syntax: $bSADROP $b\n\nSADROP forcibly de-links the given nickname from the attached user account.": "Syntax: $bSADROP $b\n\nSADROP forcibly de-links the given nickname from the attached user account.", "Syntax: $bSAGET $b\n\nSAGET queries the values of someone else's account settings. For more\ninformation on the settings and their possible values, see HELP SET.": "Syntax: $bSAGET $b\n\nSAGET queries the values of someone else's account settings. For more\ninformation on the settings and their possible values, see HELP SET.", "Syntax: $bSAREGISTER [password]$b\n\nSAREGISTER registers an account on someone else's behalf.\nThis is for use in configurations that require SASL for all connections;\nan administrator can set use this command to set up user accounts.": "Syntax: $bSAREGISTER [password]$b\n\nSAREGISTER registers an account on someone else's behalf.\nThis is for use in configurations that require SASL for all connections;\nan administrator can set use this command to set up user accounts.", "Syntax: $bSASET $b\n\nSASET modifies the values of someone else's account settings. For more\ninformation on the settings and their possible values, see HELP SET.": "Syntax: $bSASET $b\n\nSASET modifies the values of someone else's account settings. For more\ninformation on the settings and their possible values, see HELP SET.", - "Syntax: $bSENDPASS $b\n\nSENDPASS sends a password reset email to the email address associated with\nthe target account. The reset code in the email can then be used with the\n$bRESETPASS$b command.": "Syntax: $bSENDPASS $b\n\nSENDPASS sends a password reset email to the email address associated with\nthe target account. The reset code in the email can then be used with the\n$bRESETPASS$b command.", + "Syntax: $bSENDPASS $b\n\nSENDPASS sends a password reset code via nostr DM to the nostr identifier\nassociated with the target account. The reset code can then be used with the\n$bRESETPASS$b command.": "Syntax: $bSENDPASS $b\n\nSENDPASS sends a password reset code via nostr DM to the nostr identifier\nassociated with the target account. The reset code can then be used with the\n$bRESETPASS$b command.", "Syntax: $bSESSIONS [nickname]$b\n\nSESSIONS is an alias for $bCLIENTS LIST$b. See the help entry for $bCLIENTS$b\nfor more information.": "Syntax: $bSESSIONS [nickname]$b\n\nSESSIONS is an alias for $bCLIENTS LIST$b. See the help entry for $bCLIENTS$b\nfor more information.", "Syntax: $bSUSPEND ADD [DURATION duration] [reason]$b\n $bSUSPEND DEL $b\n $bSUSPEND LIST$b\n\nSuspending an account disables it (preventing new logins) and disconnects\nall associated clients. You can specify a time limit or a reason for\nthe suspension. The $bDEL$b subcommand reverses a suspension, and the $bLIST$b\ncommand lists all current suspensions.": "Syntax: $bSUSPEND ADD [DURATION duration] [reason]$b\n $bSUSPEND DEL $b\n $bSUSPEND LIST$b\n\nSuspending an account disables it (preventing new logins) and disconnects\nall associated clients. You can specify a time limit or a reason for\nthe suspension. The $bDEL$b subcommand reverses a suspension, and the $bLIST$b\ncommand lists all current suspensions.", "Syntax: $bUNREGISTER [code]$b\n\nUNREGISTER lets you delete your user account (or someone else's, if you're an\nIRC operator with the correct permissions). To prevent accidental\nunregistrations, a verification code is required; invoking the command without\na code will display the necessary code.": "Syntax: $bUNREGISTER [code]$b\n\nUNREGISTER lets you delete your user account (or someone else's, if you're an\nIRC operator with the correct permissions). To prevent accidental\nunregistrations, a verification code is required; invoking the command without\na code will display the necessary code.", - "Syntax: $bVERIFY $b\n\nVERIFY lets you complete an account registration, if the server requires email\nor other verification.": "Syntax: $bVERIFY $b\n\nVERIFY lets you complete an account registration, if the server requires email\nor other verification.", - "That account is not associated with an email address": "That account is not associated with an email address", + "Syntax: $bVERIFY $b\n\nVERIFY lets you complete an account registration, if the server requires nostr\nverification. You will receive a verification code via nostr DM.": "Syntax: $bVERIFY $b\n\nVERIFY lets you complete an account registration, if the server requires nostr\nverification. You will receive a verification code via nostr DM.", + "That account is not associated with a nostr identifier": "That account is not associated with a nostr identifier", "Try again later": "Try again later", "You must supply a password": "You must supply a password", "You're not logged into an account": "You're not logged into an account" diff --git a/vendor/github.com/ImVexed/fasturl/.gitignore b/vendor/github.com/ImVexed/fasturl/.gitignore new file mode 100644 index 00000000..1ef55336 --- /dev/null +++ b/vendor/github.com/ImVexed/fasturl/.gitignore @@ -0,0 +1,2 @@ +workdir/ +fasturl-fuzz.zip \ No newline at end of file diff --git a/vendor/github.com/ImVexed/fasturl/LICENSE b/vendor/github.com/ImVexed/fasturl/LICENSE new file mode 100644 index 00000000..a2973560 --- /dev/null +++ b/vendor/github.com/ImVexed/fasturl/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 V-X + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/ImVexed/fasturl/Makefile b/vendor/github.com/ImVexed/fasturl/Makefile new file mode 100644 index 00000000..9be92f5f --- /dev/null +++ b/vendor/github.com/ImVexed/fasturl/Makefile @@ -0,0 +1,2 @@ +gen: + ragel -G2 -Z parser.rl diff --git a/vendor/github.com/ImVexed/fasturl/parser.go b/vendor/github.com/ImVexed/fasturl/parser.go new file mode 100644 index 00000000..78e258dc --- /dev/null +++ b/vendor/github.com/ImVexed/fasturl/parser.go @@ -0,0 +1,8867 @@ +// Package fasturl is a Go URL parser using a [Ragel](http://www.colm.net/open-source/ragel/) state-machine instead of regex, or the built in standard library `url.Parse`. +// +//line parser.rl:1 +package fasturl + +import "fmt" + +//line parser.go:11 +const url_parser_start int = 45 +const url_parser_first_final int = 45 +const url_parser_error int = 0 + +const url_parser_en_main int = 45 + +//line parser.rl:96 + +// URL represents the different parts of a parsed URL +type URL struct { + Protocol string + Host string + Port string + Path string + Query string + Fragment string +} + +// ParseURL parses a given URL and returns a `URL` representing the different parts +func ParseURL(data string) (*URL, error) { + mark, host_mark, port_mark, cs, p, pe, eof := 0, 0, 0, url_parser_en_main, 0, len(data), len(data) + + u := &URL{} + +//line parser.go:39 + { + cs = url_parser_start + } + +//line parser.rl:115 + +//line parser.go:46 + { + if p == pe { + goto _test_eof + } + switch cs { + case 45: + goto st_case_45 + case 0: + goto st_case_0 + case 46: + goto st_case_46 + case 47: + goto st_case_47 + case 48: + goto st_case_48 + case 1: + goto st_case_1 + case 2: + goto st_case_2 + case 49: + goto st_case_49 + case 50: + goto st_case_50 + case 51: + goto st_case_51 + case 52: + goto st_case_52 + case 3: + goto st_case_3 + case 53: + goto st_case_53 + case 54: + goto st_case_54 + case 55: + goto st_case_55 + case 56: + goto st_case_56 + case 57: + goto st_case_57 + case 4: + goto st_case_4 + case 5: + goto st_case_5 + case 58: + goto st_case_58 + case 6: + goto st_case_6 + case 7: + goto st_case_7 + case 59: + goto st_case_59 + case 60: + goto st_case_60 + case 61: + goto st_case_61 + case 62: + goto st_case_62 + case 63: + goto st_case_63 + case 64: + goto st_case_64 + case 65: + goto st_case_65 + case 66: + goto st_case_66 + case 67: + goto st_case_67 + case 68: + goto st_case_68 + case 69: + goto st_case_69 + case 70: + goto st_case_70 + case 71: + goto st_case_71 + case 72: + goto st_case_72 + case 73: + goto st_case_73 + case 74: + goto st_case_74 + case 75: + goto st_case_75 + case 76: + goto st_case_76 + case 77: + goto st_case_77 + case 78: + goto st_case_78 + case 79: + goto st_case_79 + case 80: + goto st_case_80 + case 81: + goto st_case_81 + case 82: + goto st_case_82 + case 83: + goto st_case_83 + case 84: + goto st_case_84 + case 8: + goto st_case_8 + case 9: + goto st_case_9 + case 10: + goto st_case_10 + case 11: + goto st_case_11 + case 12: + goto st_case_12 + case 13: + goto st_case_13 + case 14: + goto st_case_14 + case 15: + goto st_case_15 + case 16: + goto st_case_16 + case 17: + goto st_case_17 + case 18: + goto st_case_18 + case 19: + goto st_case_19 + case 20: + goto st_case_20 + case 21: + goto st_case_21 + case 22: + goto st_case_22 + case 85: + goto st_case_85 + case 23: + goto st_case_23 + case 86: + goto st_case_86 + case 87: + goto st_case_87 + case 24: + goto st_case_24 + case 25: + goto st_case_25 + case 26: + goto st_case_26 + case 27: + goto st_case_27 + case 28: + goto st_case_28 + case 29: + goto st_case_29 + case 30: + goto st_case_30 + case 31: + goto st_case_31 + case 32: + goto st_case_32 + case 33: + goto st_case_33 + case 88: + goto st_case_88 + case 34: + goto st_case_34 + case 35: + goto st_case_35 + case 89: + goto st_case_89 + case 90: + goto st_case_90 + case 36: + goto st_case_36 + case 91: + goto st_case_91 + case 92: + goto st_case_92 + case 93: + goto st_case_93 + case 94: + goto st_case_94 + case 95: + goto st_case_95 + case 96: + goto st_case_96 + case 97: + goto st_case_97 + case 98: + goto st_case_98 + case 37: + goto st_case_37 + case 38: + goto st_case_38 + case 99: + goto st_case_99 + case 100: + goto st_case_100 + case 101: + goto st_case_101 + case 102: + goto st_case_102 + case 103: + goto st_case_103 + case 104: + goto st_case_104 + case 105: + goto st_case_105 + case 106: + goto st_case_106 + case 107: + goto st_case_107 + case 108: + goto st_case_108 + case 109: + goto st_case_109 + case 39: + goto st_case_39 + case 40: + goto st_case_40 + case 41: + goto st_case_41 + case 110: + goto st_case_110 + case 111: + goto st_case_111 + case 112: + goto st_case_112 + case 113: + goto st_case_113 + case 114: + goto st_case_114 + case 115: + goto st_case_115 + case 116: + goto st_case_116 + case 42: + goto st_case_42 + case 117: + goto st_case_117 + case 118: + goto st_case_118 + case 119: + goto st_case_119 + case 120: + goto st_case_120 + case 121: + goto st_case_121 + case 122: + goto st_case_122 + case 123: + goto st_case_123 + case 124: + goto st_case_124 + case 125: + goto st_case_125 + case 126: + goto st_case_126 + case 127: + goto st_case_127 + case 128: + goto st_case_128 + case 129: + goto st_case_129 + case 130: + goto st_case_130 + case 131: + goto st_case_131 + case 132: + goto st_case_132 + case 133: + goto st_case_133 + case 134: + goto st_case_134 + case 135: + goto st_case_135 + case 43: + goto st_case_43 + case 44: + goto st_case_44 + case 136: + goto st_case_136 + case 137: + goto st_case_137 + case 138: + goto st_case_138 + case 139: + goto st_case_139 + case 140: + goto st_case_140 + case 141: + goto st_case_141 + case 142: + goto st_case_142 + case 143: + goto st_case_143 + case 144: + goto st_case_144 + case 145: + goto st_case_145 + case 146: + goto st_case_146 + case 147: + goto st_case_147 + case 148: + goto st_case_148 + case 149: + goto st_case_149 + case 150: + goto st_case_150 + case 151: + goto st_case_151 + case 152: + goto st_case_152 + case 153: + goto st_case_153 + case 154: + goto st_case_154 + case 155: + goto st_case_155 + case 156: + goto st_case_156 + case 157: + goto st_case_157 + case 158: + goto st_case_158 + case 159: + goto st_case_159 + case 160: + goto st_case_160 + case 161: + goto st_case_161 + } + goto st_out + st_case_45: + switch data[p] { + case 33: + goto tr14 + case 35: + goto st47 + case 37: + goto tr15 + case 47: + goto tr44 + case 58: + goto st8 + case 61: + goto tr14 + case 63: + goto st51 + case 64: + goto st11 + case 91: + goto tr16 + case 92: + goto tr47 + case 95: + goto tr14 + case 126: + goto tr14 + } + switch { + case data[p] < 65: + if 36 <= data[p] && data[p] <= 59 { + goto tr14 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr46 + } + default: + goto tr46 + } + goto st0 + st_case_0: + st0: + cs = 0 + goto _out + tr14: +//line parser.rl:23 + + host_mark = p + + goto st46 + st46: + if p++; p == pe { + goto _test_eof46 + } + st_case_46: +//line parser.go:433 + switch data[p] { + case 33: + goto st46 + case 35: + goto tr48 + case 37: + goto st1 + case 47: + goto tr50 + case 58: + goto tr51 + case 61: + goto st46 + case 63: + goto tr52 + case 64: + goto st11 + case 92: + goto tr50 + case 95: + goto st46 + case 126: + goto st46 + } + switch { + case data[p] < 65: + if 36 <= data[p] && data[p] <= 59 { + goto st46 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr53 + } + default: + goto tr53 + } + goto st0 + tr48: +//line parser.rl:27 + + u.Host = data[host_mark:p] + + goto st47 + tr57: +//line parser.rl:37 + + if u.Path == "" { + u.Path = data[mark:p] + } + + goto st47 + tr60: +//line parser.rl:10 + mark = p +//line parser.rl:31 + + if u.Query == "" { + u.Query = data[mark:p] + } + + goto st47 + tr62: +//line parser.rl:31 + + if u.Query == "" { + u.Query = data[mark:p] + } + + goto st47 + tr64: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + + goto st47 + tr84: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:37 + + if u.Path == "" { + u.Path = data[mark:p] + } + + goto st47 + tr143: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + + goto st47 + tr228: +//line parser.rl:19 + + u.Protocol = data[0 : p-1] + + goto st47 + st47: + if p++; p == pe { + goto _test_eof47 + } + st_case_47: +//line parser.go:548 + if 32 <= data[p] && data[p] <= 126 { + goto tr54 + } + goto st0 + tr54: +//line parser.rl:10 + mark = p + goto st48 + st48: + if p++; p == pe { + goto _test_eof48 + } + st_case_48: +//line parser.go:562 + if 32 <= data[p] && data[p] <= 126 { + goto st48 + } + goto st0 + tr15: +//line parser.rl:23 + + host_mark = p + + goto st1 + st1: + if p++; p == pe { + goto _test_eof1 + } + st_case_1: +//line parser.go:578 + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st2 + } + case data[p] > 70: + if 97 <= data[p] && data[p] <= 102 { + goto st2 + } + default: + goto st2 + } + goto st0 + st2: + if p++; p == pe { + goto _test_eof2 + } + st_case_2: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st46 + } + case data[p] > 70: + if 97 <= data[p] && data[p] <= 102 { + goto st46 + } + default: + goto st46 + } + goto st0 + tr47: +//line parser.rl:10 + mark = p + goto st49 + tr50: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:10 + mark = p + goto st49 + tr66: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st49 + tr145: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st49 + st49: + if p++; p == pe { + goto _test_eof49 + } + st_case_49: +//line parser.go:651 + switch data[p] { + case 35: + goto tr57 + case 63: + goto tr58 + } + switch { + case data[p] > 46: + if 48 <= data[p] && data[p] <= 126 { + goto st50 + } + case data[p] >= 32: + goto st50 + } + goto st0 + tr86: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st50 + st50: + if p++; p == pe { + goto _test_eof50 + } + st_case_50: +//line parser.go:682 + switch data[p] { + case 35: + goto tr57 + case 63: + goto tr58 + } + if 32 <= data[p] && data[p] <= 126 { + goto st50 + } + goto st0 + tr52: +//line parser.rl:27 + + u.Host = data[host_mark:p] + + goto st51 + tr58: +//line parser.rl:37 + + if u.Path == "" { + u.Path = data[mark:p] + } + + goto st51 + tr67: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + + goto st51 + tr85: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:37 + + if u.Path == "" { + u.Path = data[mark:p] + } + + goto st51 + tr147: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + + goto st51 + tr232: +//line parser.rl:19 + + u.Protocol = data[0 : p-1] + + goto st51 + st51: + if p++; p == pe { + goto _test_eof51 + } + st_case_51: +//line parser.go:752 + if data[p] == 35 { + goto tr60 + } + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto tr59 + } + case data[p] > 62: + if 64 <= data[p] && data[p] <= 126 { + goto tr59 + } + default: + goto tr59 + } + goto st0 + tr59: +//line parser.rl:10 + mark = p + goto st52 + st52: + if p++; p == pe { + goto _test_eof52 + } + st_case_52: +//line parser.go:778 + if data[p] == 35 { + goto tr62 + } + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st52 + } + case data[p] > 62: + if 64 <= data[p] && data[p] <= 126 { + goto st52 + } + default: + goto st52 + } + goto st0 + tr51: +//line parser.rl:27 + + u.Host = data[host_mark:p] + + goto st3 + st3: + if p++; p == pe { + goto _test_eof3 + } + st_case_3: +//line parser.go:806 + switch data[p] { + case 33: + goto tr4 + case 37: + goto tr5 + case 60: + goto tr3 + case 62: + goto tr3 + case 64: + goto tr6 + case 95: + goto tr4 + case 126: + goto tr4 + } + switch { + case data[p] < 65: + switch { + case data[p] < 36: + if 32 <= data[p] && data[p] <= 34 { + goto tr3 + } + case data[p] > 46: + if 48 <= data[p] && data[p] <= 61 { + goto tr4 + } + default: + goto tr4 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto tr3 + } + case data[p] > 122: + if 123 <= data[p] && data[p] <= 125 { + goto tr3 + } + default: + goto tr4 + } + default: + goto tr4 + } + goto st0 + tr3: +//line parser.rl:11 + port_mark = p + goto st53 + tr129: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st53 + tr211: +//line parser.rl:11 + port_mark = p +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st53 + st53: + if p++; p == pe { + goto _test_eof53 + } + st_case_53: +//line parser.go:885 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st74 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr69 + } + switch { + case data[p] < 91: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 90 { + goto tr68 + } + case data[p] >= 32: + goto st54 + } + case data[p] > 96: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st54 + } + case data[p] >= 97: + goto tr68 + } + default: + goto st54 + } + goto st0 + tr68: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st54 + st54: + if p++; p == pe { + goto _test_eof54 + } + st_case_54: +//line parser.go:936 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st68 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr73 + } + switch { + case data[p] < 91: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 90 { + goto tr72 + } + case data[p] >= 32: + goto st55 + } + case data[p] > 96: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st55 + } + case data[p] >= 97: + goto tr72 + } + default: + goto st55 + } + goto st0 + tr72: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st55 + st55: + if p++; p == pe { + goto _test_eof55 + } + st_case_55: +//line parser.go:987 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st61 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr77 + } + switch { + case data[p] < 91: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 90 { + goto tr76 + } + case data[p] >= 32: + goto st56 + } + case data[p] > 96: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st56 + } + case data[p] >= 97: + goto tr76 + } + default: + goto st56 + } + goto st0 + tr76: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st56 + tr251: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st56 + st56: + if p++; p == pe { + goto _test_eof56 + } + st_case_56: +//line parser.go:1052 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st58 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr80 + } + switch { + case data[p] < 91: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 90 { + goto tr79 + } + case data[p] >= 32: + goto st57 + } + case data[p] > 96: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st57 + } + case data[p] >= 97: + goto tr79 + } + default: + goto st57 + } + goto st0 + st57: + if p++; p == pe { + goto _test_eof57 + } + st_case_57: + switch data[p] { + case 35: + goto tr64 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr66 + } + switch { + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr81 + } + case data[p] >= 65: + goto tr81 + } + goto st0 + tr125: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:10 + mark = p + goto st4 + tr81: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st4 + tr200: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st4 + st4: + if p++; p == pe { + goto _test_eof4 + } + st_case_4: +//line parser.go:1149 + if data[p] == 58 { + goto st5 + } + goto st0 + st5: + if p++; p == pe { + goto _test_eof5 + } + st_case_5: + switch data[p] { + case 47: + goto st49 + case 92: + goto st49 + } + goto st0 + st58: + if p++; p == pe { + goto _test_eof58 + } + st_case_58: + switch data[p] { + case 35: + goto tr64 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr66 + } + switch { + case data[p] < 71: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 70 { + goto tr83 + } + case data[p] >= 48: + goto st6 + } + case data[p] > 90: + switch { + case data[p] > 102: + if 103 <= data[p] && data[p] <= 122 { + goto tr81 + } + case data[p] >= 97: + goto tr83 + } + default: + goto tr81 + } + goto st0 + st6: + if p++; p == pe { + goto _test_eof6 + } + st_case_6: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st57 + } + case data[p] > 70: + if 97 <= data[p] && data[p] <= 102 { + goto st57 + } + default: + goto st57 + } + goto st0 + tr83: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st7 + st7: + if p++; p == pe { + goto _test_eof7 + } + st_case_7: +//line parser.go:1237 + if data[p] == 58 { + goto st5 + } + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st57 + } + case data[p] > 70: + if 97 <= data[p] && data[p] <= 102 { + goto st57 + } + default: + goto st57 + } + goto st0 + tr79: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st59 + tr210: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st59 + st59: + if p++; p == pe { + goto _test_eof59 + } + st_case_59: +//line parser.go:1283 + switch data[p] { + case 35: + goto tr64 + case 47: + goto tr66 + case 58: + goto st5 + case 63: + goto tr67 + case 92: + goto tr66 + } + switch { + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr81 + } + case data[p] >= 65: + goto tr81 + } + goto st0 + tr80: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st60 + tr156: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st60 + st60: + if p++; p == pe { + goto _test_eof60 + } + st_case_60: +//line parser.go:1334 + switch data[p] { + case 35: + goto tr84 + case 47: + goto tr66 + case 63: + goto tr85 + case 91: + goto st50 + } + switch { + case data[p] < 93: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 92 { + goto tr86 + } + case data[p] >= 32: + goto st50 + } + case data[p] > 96: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st50 + } + case data[p] >= 97: + goto tr86 + } + default: + goto st50 + } + goto st0 + st61: + if p++; p == pe { + goto _test_eof61 + } + st_case_61: + switch data[p] { + case 35: + goto tr64 + case 37: + goto st58 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr80 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st57 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr88 + } + case data[p] >= 58: + goto st57 + } + default: + goto st62 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st57 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st57 + } + case data[p] >= 103: + goto tr79 + } + default: + goto tr88 + } + default: + goto tr79 + } + goto st0 + st62: + if p++; p == pe { + goto _test_eof62 + } + st_case_62: + switch data[p] { + case 35: + goto tr64 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr66 + } + switch { + case data[p] < 71: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 70 { + goto tr76 + } + case data[p] >= 48: + goto st56 + } + case data[p] > 90: + switch { + case data[p] > 102: + if 103 <= data[p] && data[p] <= 122 { + goto tr81 + } + case data[p] >= 97: + goto tr76 + } + default: + goto tr81 + } + goto st0 + tr88: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st63 + st63: + if p++; p == pe { + goto _test_eof63 + } + st_case_63: +//line parser.go:1479 + switch data[p] { + case 35: + goto tr64 + case 47: + goto tr66 + case 58: + goto st5 + case 63: + goto tr67 + case 92: + goto tr66 + } + switch { + case data[p] < 71: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 70 { + goto tr76 + } + case data[p] >= 48: + goto st56 + } + case data[p] > 90: + switch { + case data[p] > 102: + if 103 <= data[p] && data[p] <= 122 { + goto tr81 + } + case data[p] >= 97: + goto tr76 + } + default: + goto tr81 + } + goto st0 + tr77: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st64 + tr153: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st64 + st64: + if p++; p == pe { + goto _test_eof64 + } + st_case_64: +//line parser.go:1544 + switch data[p] { + case 35: + goto tr84 + case 37: + goto st66 + case 47: + goto tr66 + case 63: + goto tr85 + case 91: + goto st65 + } + switch { + case data[p] < 93: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 92 { + goto tr91 + } + case data[p] >= 32: + goto st65 + } + case data[p] > 96: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st65 + } + case data[p] >= 97: + goto tr91 + } + default: + goto st65 + } + goto st0 + tr91: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st65 + st65: + if p++; p == pe { + goto _test_eof65 + } + st_case_65: +//line parser.go:1595 + switch data[p] { + case 35: + goto tr84 + case 47: + goto tr86 + case 63: + goto tr85 + case 91: + goto st50 + } + switch { + case data[p] < 93: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 92 { + goto tr86 + } + case data[p] >= 32: + goto st50 + } + case data[p] > 96: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st50 + } + case data[p] >= 97: + goto tr86 + } + default: + goto st50 + } + goto st0 + st66: + if p++; p == pe { + goto _test_eof66 + } + st_case_66: + switch data[p] { + case 35: + goto tr84 + case 47: + goto tr86 + case 63: + goto tr85 + case 91: + goto st50 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st50 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr93 + } + case data[p] >= 58: + goto st50 + } + default: + goto st67 + } + case data[p] > 92: + switch { + case data[p] < 97: + if 93 <= data[p] && data[p] <= 96 { + goto st50 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st50 + } + case data[p] >= 103: + goto tr86 + } + default: + goto tr93 + } + default: + goto tr86 + } + goto st0 + tr93: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st67 + st67: + if p++; p == pe { + goto _test_eof67 + } + st_case_67: +//line parser.go:1700 + switch data[p] { + case 35: + goto tr57 + case 63: + goto tr58 + } + switch { + case data[p] < 65: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 47 { + goto st50 + } + case data[p] > 57: + if 58 <= data[p] && data[p] <= 64 { + goto st50 + } + default: + goto st65 + } + case data[p] > 70: + switch { + case data[p] < 97: + if 71 <= data[p] && data[p] <= 96 { + goto st50 + } + case data[p] > 102: + if 103 <= data[p] && data[p] <= 126 { + goto st50 + } + default: + goto st65 + } + default: + goto st65 + } + goto st0 + st68: + if p++; p == pe { + goto _test_eof68 + } + st_case_68: + switch data[p] { + case 35: + goto tr64 + case 37: + goto st61 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr77 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st56 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr95 + } + case data[p] >= 58: + goto st56 + } + default: + goto st69 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st56 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st56 + } + case data[p] >= 103: + goto tr76 + } + default: + goto tr95 + } + default: + goto tr76 + } + goto st0 + tr95: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st69 + st69: + if p++; p == pe { + goto _test_eof69 + } + st_case_69: +//line parser.go:1811 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st58 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr80 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st57 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr72 + } + case data[p] >= 58: + goto st57 + } + default: + goto st55 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st57 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st57 + } + case data[p] >= 103: + goto tr79 + } + default: + goto tr72 + } + default: + goto tr79 + } + goto st0 + tr73: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st70 + tr149: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st70 + st70: + if p++; p == pe { + goto _test_eof70 + } + st_case_70: +//line parser.go:1894 + switch data[p] { + case 35: + goto tr84 + case 37: + goto st72 + case 47: + goto tr66 + case 63: + goto tr85 + case 91: + goto st71 + } + switch { + case data[p] < 93: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 92 { + goto tr98 + } + case data[p] >= 32: + goto st71 + } + case data[p] > 96: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st71 + } + case data[p] >= 97: + goto tr98 + } + default: + goto st71 + } + goto st0 + tr98: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st71 + st71: + if p++; p == pe { + goto _test_eof71 + } + st_case_71: +//line parser.go:1945 + switch data[p] { + case 35: + goto tr84 + case 37: + goto st66 + case 47: + goto tr86 + case 63: + goto tr85 + case 91: + goto st65 + } + switch { + case data[p] < 93: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 92 { + goto tr91 + } + case data[p] >= 32: + goto st65 + } + case data[p] > 96: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st65 + } + case data[p] >= 97: + goto tr91 + } + default: + goto st65 + } + goto st0 + st72: + if p++; p == pe { + goto _test_eof72 + } + st_case_72: + switch data[p] { + case 35: + goto tr84 + case 37: + goto st66 + case 47: + goto tr86 + case 63: + goto tr85 + case 91: + goto st65 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st65 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr100 + } + case data[p] >= 58: + goto st65 + } + default: + goto st73 + } + case data[p] > 92: + switch { + case data[p] < 97: + if 93 <= data[p] && data[p] <= 96 { + goto st65 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st65 + } + case data[p] >= 103: + goto tr91 + } + default: + goto tr100 + } + default: + goto tr91 + } + goto st0 + tr100: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st73 + st73: + if p++; p == pe { + goto _test_eof73 + } + st_case_73: +//line parser.go:2054 + switch data[p] { + case 35: + goto tr84 + case 47: + goto tr86 + case 63: + goto tr85 + case 91: + goto st50 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st50 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr98 + } + case data[p] >= 58: + goto st50 + } + default: + goto st71 + } + case data[p] > 92: + switch { + case data[p] < 97: + if 93 <= data[p] && data[p] <= 96 { + goto st50 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st50 + } + case data[p] >= 103: + goto tr86 + } + default: + goto tr98 + } + default: + goto tr86 + } + goto st0 + st74: + if p++; p == pe { + goto _test_eof74 + } + st_case_74: + switch data[p] { + case 35: + goto tr64 + case 37: + goto st68 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr73 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st55 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr102 + } + case data[p] >= 58: + goto st55 + } + default: + goto st75 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st55 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st55 + } + case data[p] >= 103: + goto tr72 + } + default: + goto tr102 + } + default: + goto tr72 + } + goto st0 + tr102: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st75 + st75: + if p++; p == pe { + goto _test_eof75 + } + st_case_75: +//line parser.go:2179 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st61 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr77 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st56 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr68 + } + case data[p] >= 58: + goto st56 + } + default: + goto st54 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st56 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st56 + } + case data[p] >= 103: + goto tr76 + } + default: + goto tr68 + } + default: + goto tr76 + } + goto st0 + tr69: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st76 + tr239: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st76 + st76: + if p++; p == pe { + goto _test_eof76 + } + st_case_76: +//line parser.go:2262 + switch data[p] { + case 35: + goto tr84 + case 37: + goto st78 + case 47: + goto tr66 + case 63: + goto tr85 + case 91: + goto st77 + } + switch { + case data[p] < 93: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 92 { + goto tr105 + } + case data[p] >= 32: + goto st77 + } + case data[p] > 96: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st77 + } + case data[p] >= 97: + goto tr105 + } + default: + goto st77 + } + goto st0 + tr105: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st77 + st77: + if p++; p == pe { + goto _test_eof77 + } + st_case_77: +//line parser.go:2313 + switch data[p] { + case 35: + goto tr84 + case 37: + goto st72 + case 47: + goto tr86 + case 63: + goto tr85 + case 91: + goto st71 + } + switch { + case data[p] < 93: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 92 { + goto tr98 + } + case data[p] >= 32: + goto st71 + } + case data[p] > 96: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st71 + } + case data[p] >= 97: + goto tr98 + } + default: + goto st71 + } + goto st0 + st78: + if p++; p == pe { + goto _test_eof78 + } + st_case_78: + switch data[p] { + case 35: + goto tr84 + case 37: + goto st72 + case 47: + goto tr86 + case 63: + goto tr85 + case 91: + goto st71 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st71 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr107 + } + case data[p] >= 58: + goto st71 + } + default: + goto st79 + } + case data[p] > 92: + switch { + case data[p] < 97: + if 93 <= data[p] && data[p] <= 96 { + goto st71 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st71 + } + case data[p] >= 103: + goto tr98 + } + default: + goto tr107 + } + default: + goto tr98 + } + goto st0 + tr107: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st79 + st79: + if p++; p == pe { + goto _test_eof79 + } + st_case_79: +//line parser.go:2422 + switch data[p] { + case 35: + goto tr84 + case 37: + goto st66 + case 47: + goto tr86 + case 63: + goto tr85 + case 91: + goto st65 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st65 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr105 + } + case data[p] >= 58: + goto st65 + } + default: + goto st77 + } + case data[p] > 92: + switch { + case data[p] < 97: + if 93 <= data[p] && data[p] <= 96 { + goto st65 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st65 + } + case data[p] >= 103: + goto tr91 + } + default: + goto tr105 + } + default: + goto tr91 + } + goto st0 + tr4: +//line parser.rl:11 + port_mark = p + goto st80 + tr137: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st80 + tr160: +//line parser.rl:11 + port_mark = p +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st80 + tr231: +//line parser.rl:19 + + u.Protocol = data[0 : p-1] + +//line parser.rl:11 + port_mark = p + goto st80 + st80: + if p++; p == pe { + goto _test_eof80 + } + st_case_80: +//line parser.go:2515 + switch data[p] { + case 33: + goto st81 + case 35: + goto tr64 + case 37: + goto st142 + case 47: + goto tr66 + case 60: + goto st54 + case 62: + goto st54 + case 63: + goto tr67 + case 64: + goto st119 + case 92: + goto tr69 + case 95: + goto st81 + case 126: + goto st81 + } + switch { + case data[p] < 65: + switch { + case data[p] > 34: + if 36 <= data[p] && data[p] <= 61 { + goto st81 + } + case data[p] >= 32: + goto st54 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st54 + } + case data[p] > 122: + if 123 <= data[p] && data[p] <= 125 { + goto st54 + } + default: + goto tr111 + } + default: + goto tr111 + } + goto st0 + tr111: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st81 + st81: + if p++; p == pe { + goto _test_eof81 + } + st_case_81: +//line parser.go:2582 + switch data[p] { + case 33: + goto st82 + case 35: + goto tr64 + case 37: + goto st140 + case 47: + goto tr66 + case 60: + goto st55 + case 62: + goto st55 + case 63: + goto tr67 + case 64: + goto st112 + case 92: + goto tr73 + case 95: + goto st82 + case 126: + goto st82 + } + switch { + case data[p] < 65: + switch { + case data[p] > 34: + if 36 <= data[p] && data[p] <= 61 { + goto st82 + } + case data[p] >= 32: + goto st55 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st55 + } + case data[p] > 122: + if 123 <= data[p] && data[p] <= 125 { + goto st55 + } + default: + goto tr115 + } + default: + goto tr115 + } + goto st0 + tr115: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st82 + st82: + if p++; p == pe { + goto _test_eof82 + } + st_case_82: +//line parser.go:2649 + switch data[p] { + case 33: + goto st83 + case 35: + goto tr64 + case 37: + goto st137 + case 47: + goto tr66 + case 60: + goto st56 + case 62: + goto st56 + case 63: + goto tr67 + case 64: + goto st108 + case 92: + goto tr77 + case 95: + goto st83 + case 126: + goto st83 + } + switch { + case data[p] < 65: + switch { + case data[p] > 34: + if 36 <= data[p] && data[p] <= 61 { + goto st83 + } + case data[p] >= 32: + goto st56 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st56 + } + case data[p] > 122: + if 123 <= data[p] && data[p] <= 125 { + goto st56 + } + default: + goto tr119 + } + default: + goto tr119 + } + goto st0 + tr119: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st83 + st83: + if p++; p == pe { + goto _test_eof83 + } + st_case_83: +//line parser.go:2716 + switch data[p] { + case 33: + goto st84 + case 35: + goto tr64 + case 37: + goto st88 + case 47: + goto tr66 + case 60: + goto st57 + case 62: + goto st57 + case 63: + goto tr67 + case 64: + goto st89 + case 92: + goto tr80 + case 95: + goto st84 + case 126: + goto st84 + } + switch { + case data[p] < 65: + switch { + case data[p] > 34: + if 36 <= data[p] && data[p] <= 61 { + goto st84 + } + case data[p] >= 32: + goto st57 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st57 + } + case data[p] > 122: + if 123 <= data[p] && data[p] <= 125 { + goto st57 + } + default: + goto tr122 + } + default: + goto tr122 + } + goto st0 + st84: + if p++; p == pe { + goto _test_eof84 + } + st_case_84: + switch data[p] { + case 33: + goto st8 + case 35: + goto tr64 + case 37: + goto st9 + case 47: + goto tr66 + case 61: + goto st8 + case 63: + goto tr67 + case 64: + goto st11 + case 92: + goto tr66 + case 95: + goto st8 + case 126: + goto st8 + } + switch { + case data[p] < 65: + if 36 <= data[p] && data[p] <= 59 { + goto st8 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr123 + } + default: + goto tr123 + } + goto st0 + st8: + if p++; p == pe { + goto _test_eof8 + } + st_case_8: + switch data[p] { + case 33: + goto st8 + case 37: + goto st9 + case 61: + goto st8 + case 64: + goto st11 + case 95: + goto st8 + case 126: + goto st8 + } + switch { + case data[p] < 48: + if 36 <= data[p] && data[p] <= 46 { + goto st8 + } + case data[p] > 59: + switch { + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto st8 + } + case data[p] >= 65: + goto st8 + } + default: + goto st8 + } + goto st0 + st9: + if p++; p == pe { + goto _test_eof9 + } + st_case_9: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st10 + } + case data[p] > 70: + if 97 <= data[p] && data[p] <= 102 { + goto st10 + } + default: + goto st10 + } + goto st0 + st10: + if p++; p == pe { + goto _test_eof10 + } + st_case_10: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st8 + } + case data[p] > 70: + if 97 <= data[p] && data[p] <= 102 { + goto st8 + } + default: + goto st8 + } + goto st0 + st11: + if p++; p == pe { + goto _test_eof11 + } + st_case_11: + switch data[p] { + case 33: + goto tr14 + case 37: + goto tr15 + case 58: + goto st8 + case 61: + goto tr14 + case 64: + goto st11 + case 91: + goto tr16 + case 95: + goto tr14 + case 126: + goto tr14 + } + switch { + case data[p] < 48: + if 36 <= data[p] && data[p] <= 46 { + goto tr14 + } + case data[p] > 59: + switch { + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr14 + } + case data[p] >= 65: + goto tr14 + } + default: + goto tr14 + } + goto st0 + tr16: +//line parser.rl:23 + + host_mark = p + + goto st12 + st12: + if p++; p == pe { + goto _test_eof12 + } + st_case_12: +//line parser.go:2933 + if data[p] == 118 { + goto st28 + } + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 58 { + goto st13 + } + case data[p] > 70: + if 97 <= data[p] && data[p] <= 102 { + goto st13 + } + default: + goto st13 + } + goto st0 + st13: + if p++; p == pe { + goto _test_eof13 + } + st_case_13: + switch data[p] { + case 58: + goto st13 + case 93: + goto st85 + } + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st14 + } + case data[p] > 70: + if 97 <= data[p] && data[p] <= 102 { + goto st13 + } + default: + goto st13 + } + goto st0 + st14: + if p++; p == pe { + goto _test_eof14 + } + st_case_14: + switch data[p] { + case 46: + goto st15 + case 58: + goto st13 + case 93: + goto st85 + } + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st14 + } + case data[p] > 70: + if 97 <= data[p] && data[p] <= 102 { + goto st13 + } + default: + goto st13 + } + goto st0 + st15: + if p++; p == pe { + goto _test_eof15 + } + st_case_15: + if 48 <= data[p] && data[p] <= 57 { + goto st16 + } + goto st0 + st16: + if p++; p == pe { + goto _test_eof16 + } + st_case_16: + if data[p] == 46 { + goto st17 + } + if 48 <= data[p] && data[p] <= 57 { + goto st26 + } + goto st0 + st17: + if p++; p == pe { + goto _test_eof17 + } + st_case_17: + if 48 <= data[p] && data[p] <= 57 { + goto st18 + } + goto st0 + st18: + if p++; p == pe { + goto _test_eof18 + } + st_case_18: + if data[p] == 46 { + goto st19 + } + if 48 <= data[p] && data[p] <= 57 { + goto st24 + } + goto st0 + st19: + if p++; p == pe { + goto _test_eof19 + } + st_case_19: + if 48 <= data[p] && data[p] <= 57 { + goto st20 + } + goto st0 + st20: + if p++; p == pe { + goto _test_eof20 + } + st_case_20: + if data[p] == 93 { + goto st85 + } + if 48 <= data[p] && data[p] <= 57 { + goto st21 + } + goto st0 + st21: + if p++; p == pe { + goto _test_eof21 + } + st_case_21: + if data[p] == 93 { + goto st85 + } + if 48 <= data[p] && data[p] <= 57 { + goto st22 + } + goto st0 + st22: + if p++; p == pe { + goto _test_eof22 + } + st_case_22: + if data[p] == 93 { + goto st85 + } + goto st0 + st85: + if p++; p == pe { + goto _test_eof85 + } + st_case_85: + switch data[p] { + case 35: + goto tr48 + case 47: + goto tr50 + case 58: + goto tr124 + case 63: + goto tr52 + case 92: + goto tr50 + } + switch { + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr125 + } + case data[p] >= 65: + goto tr125 + } + goto st0 + tr124: +//line parser.rl:27 + + u.Host = data[host_mark:p] + + goto st23 + st23: + if p++; p == pe { + goto _test_eof23 + } + st_case_23: +//line parser.go:3121 + if data[p] == 37 { + goto tr31 + } + switch { + case data[p] < 36: + if 32 <= data[p] && data[p] <= 34 { + goto tr3 + } + case data[p] > 46: + switch { + case data[p] > 62: + if 64 <= data[p] && data[p] <= 126 { + goto tr3 + } + case data[p] >= 48: + goto tr3 + } + default: + goto tr3 + } + goto st0 + tr31: +//line parser.rl:11 + port_mark = p + goto st86 + st86: + if p++; p == pe { + goto _test_eof86 + } + st_case_86: +//line parser.go:3152 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st74 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr69 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st54 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr127 + } + case data[p] >= 58: + goto st54 + } + default: + goto st87 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st54 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st54 + } + case data[p] >= 103: + goto tr68 + } + default: + goto tr127 + } + default: + goto tr68 + } + goto st0 + tr127: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st87 + st87: + if p++; p == pe { + goto _test_eof87 + } + st_case_87: +//line parser.go:3221 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st68 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr73 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st55 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr129 + } + case data[p] >= 58: + goto st55 + } + default: + goto st53 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st55 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st55 + } + case data[p] >= 103: + goto tr72 + } + default: + goto tr129 + } + default: + goto tr72 + } + goto st0 + st24: + if p++; p == pe { + goto _test_eof24 + } + st_case_24: + if data[p] == 46 { + goto st19 + } + if 48 <= data[p] && data[p] <= 57 { + goto st25 + } + goto st0 + st25: + if p++; p == pe { + goto _test_eof25 + } + st_case_25: + if data[p] == 46 { + goto st19 + } + goto st0 + st26: + if p++; p == pe { + goto _test_eof26 + } + st_case_26: + if data[p] == 46 { + goto st17 + } + if 48 <= data[p] && data[p] <= 57 { + goto st27 + } + goto st0 + st27: + if p++; p == pe { + goto _test_eof27 + } + st_case_27: + if data[p] == 46 { + goto st17 + } + goto st0 + st28: + if p++; p == pe { + goto _test_eof28 + } + st_case_28: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st29 + } + case data[p] > 70: + if 97 <= data[p] && data[p] <= 102 { + goto st29 + } + default: + goto st29 + } + goto st0 + st29: + if p++; p == pe { + goto _test_eof29 + } + st_case_29: + if data[p] == 46 { + goto st30 + } + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st29 + } + case data[p] > 70: + if 97 <= data[p] && data[p] <= 102 { + goto st29 + } + default: + goto st29 + } + goto st0 + st30: + if p++; p == pe { + goto _test_eof30 + } + st_case_30: + switch data[p] { + case 33: + goto st31 + case 36: + goto st31 + case 61: + goto st31 + case 95: + goto st31 + case 126: + goto st31 + } + switch { + case data[p] < 48: + if 38 <= data[p] && data[p] <= 46 { + goto st31 + } + case data[p] > 59: + switch { + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto st31 + } + case data[p] >= 65: + goto st31 + } + default: + goto st31 + } + goto st0 + st31: + if p++; p == pe { + goto _test_eof31 + } + st_case_31: + switch data[p] { + case 33: + goto st31 + case 36: + goto st31 + case 61: + goto st31 + case 93: + goto st85 + case 95: + goto st31 + case 126: + goto st31 + } + switch { + case data[p] < 48: + if 38 <= data[p] && data[p] <= 46 { + goto st31 + } + case data[p] > 59: + switch { + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto st31 + } + case data[p] >= 65: + goto st31 + } + default: + goto st31 + } + goto st0 + tr123: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st32 + st32: + if p++; p == pe { + goto _test_eof32 + } + st_case_32: +//line parser.go:3443 + switch data[p] { + case 33: + goto st8 + case 37: + goto st9 + case 58: + goto st33 + case 61: + goto st8 + case 64: + goto st11 + case 95: + goto st8 + case 126: + goto st8 + } + switch { + case data[p] < 48: + if 36 <= data[p] && data[p] <= 46 { + goto st8 + } + case data[p] > 59: + switch { + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto st8 + } + case data[p] >= 65: + goto st8 + } + default: + goto st8 + } + goto st0 + st33: + if p++; p == pe { + goto _test_eof33 + } + st_case_33: + switch data[p] { + case 33: + goto st8 + case 37: + goto st9 + case 47: + goto st49 + case 61: + goto st8 + case 64: + goto st11 + case 92: + goto st49 + case 95: + goto st8 + case 126: + goto st8 + } + switch { + case data[p] < 65: + if 36 <= data[p] && data[p] <= 59 { + goto st8 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto st8 + } + default: + goto st8 + } + goto st0 + st88: + if p++; p == pe { + goto _test_eof88 + } + st_case_88: + switch data[p] { + case 35: + goto tr64 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr66 + } + switch { + case data[p] < 71: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 70 { + goto tr131 + } + case data[p] >= 48: + goto st34 + } + case data[p] > 90: + switch { + case data[p] > 102: + if 103 <= data[p] && data[p] <= 122 { + goto tr81 + } + case data[p] >= 97: + goto tr131 + } + default: + goto tr81 + } + goto st0 + st34: + if p++; p == pe { + goto _test_eof34 + } + st_case_34: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st84 + } + case data[p] > 70: + if 97 <= data[p] && data[p] <= 102 { + goto st84 + } + default: + goto st84 + } + goto st0 + tr131: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st35 + st35: + if p++; p == pe { + goto _test_eof35 + } + st_case_35: +//line parser.go:3585 + if data[p] == 58 { + goto st5 + } + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st84 + } + case data[p] > 70: + if 97 <= data[p] && data[p] <= 102 { + goto st84 + } + default: + goto st84 + } + goto st0 + st89: + if p++; p == pe { + goto _test_eof89 + } + st_case_89: + switch data[p] { + case 33: + goto tr14 + case 35: + goto tr64 + case 37: + goto tr15 + case 47: + goto tr66 + case 58: + goto st8 + case 61: + goto tr14 + case 63: + goto tr67 + case 64: + goto st11 + case 91: + goto tr16 + case 92: + goto tr66 + case 95: + goto tr14 + case 126: + goto tr14 + } + switch { + case data[p] < 65: + if 36 <= data[p] && data[p] <= 59 { + goto tr14 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr132 + } + default: + goto tr132 + } + goto st0 + tr53: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:10 + mark = p + goto st90 + tr132: +//line parser.rl:23 + + host_mark = p + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st90 + tr157: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st90 + tr223: +//line parser.rl:23 + + host_mark = p + +//line parser.rl:10 + mark = p + goto st90 + st90: + if p++; p == pe { + goto _test_eof90 + } + st_case_90: +//line parser.go:3695 + switch data[p] { + case 33: + goto st46 + case 35: + goto tr48 + case 37: + goto st1 + case 47: + goto tr50 + case 58: + goto tr133 + case 61: + goto st46 + case 63: + goto tr52 + case 64: + goto st11 + case 92: + goto tr50 + case 95: + goto st46 + case 126: + goto st46 + } + switch { + case data[p] < 65: + if 36 <= data[p] && data[p] <= 59 { + goto st46 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr53 + } + default: + goto tr53 + } + goto st0 + tr133: +//line parser.rl:27 + + u.Host = data[host_mark:p] + + goto st36 + st36: + if p++; p == pe { + goto _test_eof36 + } + st_case_36: +//line parser.go:3744 + switch data[p] { + case 33: + goto tr4 + case 37: + goto tr5 + case 47: + goto st49 + case 60: + goto tr3 + case 62: + goto tr3 + case 64: + goto tr6 + case 92: + goto tr39 + case 95: + goto tr4 + case 126: + goto tr4 + } + switch { + case data[p] < 65: + switch { + case data[p] > 34: + if 36 <= data[p] && data[p] <= 61 { + goto tr4 + } + case data[p] >= 32: + goto tr3 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto tr3 + } + case data[p] > 122: + if 123 <= data[p] && data[p] <= 125 { + goto tr3 + } + default: + goto tr4 + } + default: + goto tr4 + } + goto st0 + tr5: +//line parser.rl:11 + port_mark = p + goto st91 + st91: + if p++; p == pe { + goto _test_eof91 + } + st_case_91: +//line parser.go:3801 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st74 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr69 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st54 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr135 + } + case data[p] >= 58: + goto st54 + } + default: + goto st92 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st54 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st54 + } + case data[p] >= 103: + goto tr68 + } + default: + goto tr135 + } + default: + goto tr68 + } + goto st0 + tr135: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st92 + st92: + if p++; p == pe { + goto _test_eof92 + } + st_case_92: +//line parser.go:3870 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st68 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr73 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st55 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr137 + } + case data[p] >= 58: + goto st55 + } + default: + goto st80 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st55 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st55 + } + case data[p] >= 103: + goto tr72 + } + default: + goto tr137 + } + default: + goto tr72 + } + goto st0 + tr6: +//line parser.rl:11 + port_mark = p + goto st93 + tr233: +//line parser.rl:19 + + u.Protocol = data[0 : p-1] + +//line parser.rl:11 + port_mark = p + goto st93 + st93: + if p++; p == pe { + goto _test_eof93 + } + st_case_93: +//line parser.go:3941 + switch data[p] { + case 33: + goto tr138 + case 35: + goto tr64 + case 37: + goto tr139 + case 47: + goto tr66 + case 58: + goto st81 + case 60: + goto st54 + case 62: + goto st54 + case 63: + goto tr67 + case 64: + goto st119 + case 91: + goto tr141 + case 92: + goto tr69 + case 95: + goto tr138 + case 126: + goto tr138 + } + switch { + case data[p] < 65: + switch { + case data[p] > 34: + if 36 <= data[p] && data[p] <= 61 { + goto tr138 + } + case data[p] >= 32: + goto st54 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 93 <= data[p] && data[p] <= 96 { + goto st54 + } + case data[p] > 122: + if 123 <= data[p] && data[p] <= 125 { + goto st54 + } + default: + goto tr140 + } + default: + goto tr140 + } + goto st0 + tr138: +//line parser.rl:23 + + host_mark = p + + goto st94 + tr190: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st94 + tr140: +//line parser.rl:23 + + host_mark = p + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st94 + tr238: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st94 + st94: + if p++; p == pe { + goto _test_eof94 + } + st_case_94: +//line parser.go:4046 + switch data[p] { + case 33: + goto st95 + case 35: + goto tr143 + case 37: + goto st110 + case 47: + goto tr145 + case 58: + goto tr146 + case 60: + goto st55 + case 62: + goto st55 + case 63: + goto tr147 + case 64: + goto st112 + case 92: + goto tr149 + case 95: + goto st95 + case 126: + goto st95 + } + switch { + case data[p] < 65: + switch { + case data[p] > 34: + if 36 <= data[p] && data[p] <= 61 { + goto st95 + } + case data[p] >= 32: + goto st55 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st55 + } + case data[p] > 122: + if 123 <= data[p] && data[p] <= 125 { + goto st55 + } + default: + goto tr148 + } + default: + goto tr148 + } + goto st0 + tr191: +//line parser.rl:23 + + host_mark = p + + goto st95 + tr178: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st95 + tr193: +//line parser.rl:23 + + host_mark = p + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st95 + tr148: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st95 + st95: + if p++; p == pe { + goto _test_eof95 + } + st_case_95: +//line parser.go:4149 + switch data[p] { + case 33: + goto st96 + case 35: + goto tr143 + case 37: + goto st105 + case 47: + goto tr145 + case 58: + goto tr146 + case 60: + goto st56 + case 62: + goto st56 + case 63: + goto tr147 + case 64: + goto st108 + case 92: + goto tr153 + case 95: + goto st96 + case 126: + goto st96 + } + switch { + case data[p] < 65: + switch { + case data[p] > 34: + if 36 <= data[p] && data[p] <= 61 { + goto st96 + } + case data[p] >= 32: + goto st56 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st56 + } + case data[p] > 122: + if 123 <= data[p] && data[p] <= 125 { + goto st56 + } + default: + goto tr152 + } + default: + goto tr152 + } + goto st0 + tr179: +//line parser.rl:23 + + host_mark = p + + goto st96 + tr169: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st96 + tr181: +//line parser.rl:23 + + host_mark = p + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st96 + tr152: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st96 + st96: + if p++; p == pe { + goto _test_eof96 + } + st_case_96: +//line parser.go:4252 + switch data[p] { + case 33: + goto st97 + case 35: + goto tr143 + case 37: + goto st98 + case 47: + goto tr145 + case 58: + goto tr146 + case 60: + goto st57 + case 62: + goto st57 + case 63: + goto tr147 + case 64: + goto st89 + case 92: + goto tr156 + case 95: + goto st97 + case 126: + goto st97 + } + switch { + case data[p] < 65: + switch { + case data[p] > 34: + if 36 <= data[p] && data[p] <= 61 { + goto st97 + } + case data[p] >= 32: + goto st57 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st57 + } + case data[p] > 122: + if 123 <= data[p] && data[p] <= 125 { + goto st57 + } + default: + goto tr155 + } + default: + goto tr155 + } + goto st0 + tr170: +//line parser.rl:23 + + host_mark = p + + goto st97 + st97: + if p++; p == pe { + goto _test_eof97 + } + st_case_97: +//line parser.go:4317 + switch data[p] { + case 33: + goto st46 + case 35: + goto tr143 + case 37: + goto st1 + case 47: + goto tr145 + case 58: + goto tr51 + case 61: + goto st46 + case 63: + goto tr147 + case 64: + goto st11 + case 92: + goto tr145 + case 95: + goto st46 + case 126: + goto st46 + } + switch { + case data[p] < 65: + if 36 <= data[p] && data[p] <= 59 { + goto st46 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr157 + } + default: + goto tr157 + } + goto st0 + tr171: +//line parser.rl:23 + + host_mark = p + + goto st98 + st98: + if p++; p == pe { + goto _test_eof98 + } + st_case_98: +//line parser.go:4366 + switch data[p] { + case 35: + goto tr64 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr66 + } + switch { + case data[p] < 71: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 70 { + goto tr159 + } + case data[p] >= 48: + goto st37 + } + case data[p] > 90: + switch { + case data[p] > 102: + if 103 <= data[p] && data[p] <= 122 { + goto tr81 + } + case data[p] >= 97: + goto tr159 + } + default: + goto tr81 + } + goto st0 + st37: + if p++; p == pe { + goto _test_eof37 + } + st_case_37: + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st97 + } + case data[p] > 70: + if 97 <= data[p] && data[p] <= 102 { + goto st97 + } + default: + goto st97 + } + goto st0 + tr159: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st38 + st38: + if p++; p == pe { + goto _test_eof38 + } + st_case_38: +//line parser.go:4433 + if data[p] == 58 { + goto st5 + } + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st97 + } + case data[p] > 70: + if 97 <= data[p] && data[p] <= 102 { + goto st97 + } + default: + goto st97 + } + goto st0 + tr146: +//line parser.rl:27 + + u.Host = data[host_mark:p] + + goto st99 + st99: + if p++; p == pe { + goto _test_eof99 + } + st_case_99: +//line parser.go:4461 + switch data[p] { + case 33: + goto tr4 + case 35: + goto tr64 + case 37: + goto tr5 + case 47: + goto tr66 + case 60: + goto tr3 + case 62: + goto tr3 + case 63: + goto tr67 + case 64: + goto tr6 + case 92: + goto tr161 + case 95: + goto tr4 + case 126: + goto tr4 + } + switch { + case data[p] < 65: + switch { + case data[p] > 34: + if 36 <= data[p] && data[p] <= 61 { + goto tr4 + } + case data[p] >= 32: + goto tr3 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto tr3 + } + case data[p] > 122: + if 123 <= data[p] && data[p] <= 125 { + goto tr3 + } + default: + goto tr160 + } + default: + goto tr160 + } + goto st0 + tr39: +//line parser.rl:11 + port_mark = p + goto st100 + tr161: +//line parser.rl:11 + port_mark = p +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st100 + tr236: +//line parser.rl:19 + + u.Protocol = data[0 : p-1] + +//line parser.rl:11 + port_mark = p +//line parser.rl:10 + mark = p + goto st100 + st100: + if p++; p == pe { + goto _test_eof100 + } + st_case_100: +//line parser.go:4544 + switch data[p] { + case 35: + goto tr84 + case 37: + goto st102 + case 47: + goto tr66 + case 63: + goto tr85 + case 91: + goto st101 + } + switch { + case data[p] < 93: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 92 { + goto tr164 + } + case data[p] >= 32: + goto st101 + } + case data[p] > 96: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st101 + } + case data[p] >= 97: + goto tr164 + } + default: + goto st101 + } + goto st0 + tr164: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st101 + st101: + if p++; p == pe { + goto _test_eof101 + } + st_case_101: +//line parser.go:4595 + switch data[p] { + case 35: + goto tr84 + case 37: + goto st78 + case 47: + goto tr86 + case 63: + goto tr85 + case 91: + goto st77 + } + switch { + case data[p] < 93: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 92 { + goto tr105 + } + case data[p] >= 32: + goto st77 + } + case data[p] > 96: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st77 + } + case data[p] >= 97: + goto tr105 + } + default: + goto st77 + } + goto st0 + st102: + if p++; p == pe { + goto _test_eof102 + } + st_case_102: + switch data[p] { + case 35: + goto tr84 + case 37: + goto st78 + case 47: + goto tr86 + case 63: + goto tr85 + case 91: + goto st77 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st77 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr166 + } + case data[p] >= 58: + goto st77 + } + default: + goto st103 + } + case data[p] > 92: + switch { + case data[p] < 97: + if 93 <= data[p] && data[p] <= 96 { + goto st77 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st77 + } + case data[p] >= 103: + goto tr105 + } + default: + goto tr166 + } + default: + goto tr105 + } + goto st0 + tr166: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st103 + st103: + if p++; p == pe { + goto _test_eof103 + } + st_case_103: +//line parser.go:4704 + switch data[p] { + case 35: + goto tr84 + case 37: + goto st72 + case 47: + goto tr86 + case 63: + goto tr85 + case 91: + goto st71 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st71 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr164 + } + case data[p] >= 58: + goto st71 + } + default: + goto st101 + } + case data[p] > 92: + switch { + case data[p] < 97: + if 93 <= data[p] && data[p] <= 96 { + goto st71 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st71 + } + case data[p] >= 103: + goto tr98 + } + default: + goto tr164 + } + default: + goto tr98 + } + goto st0 + tr172: +//line parser.rl:23 + + host_mark = p + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st104 + tr155: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st104 + st104: + if p++; p == pe { + goto _test_eof104 + } + st_case_104: +//line parser.go:4791 + switch data[p] { + case 33: + goto st46 + case 35: + goto tr143 + case 37: + goto st1 + case 47: + goto tr145 + case 58: + goto tr133 + case 61: + goto st46 + case 63: + goto tr147 + case 64: + goto st11 + case 92: + goto tr145 + case 95: + goto st46 + case 126: + goto st46 + } + switch { + case data[p] < 65: + if 36 <= data[p] && data[p] <= 59 { + goto st46 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr157 + } + default: + goto tr157 + } + goto st0 + tr180: +//line parser.rl:23 + + host_mark = p + + goto st105 + st105: + if p++; p == pe { + goto _test_eof105 + } + st_case_105: +//line parser.go:4840 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st58 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr80 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st57 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr168 + } + case data[p] >= 58: + goto st57 + } + default: + goto st106 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st57 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st57 + } + case data[p] >= 103: + goto tr79 + } + default: + goto tr168 + } + default: + goto tr79 + } + goto st0 + st106: + if p++; p == pe { + goto _test_eof106 + } + st_case_106: + switch data[p] { + case 35: + goto tr64 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr66 + } + switch { + case data[p] < 71: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 70 { + goto tr169 + } + case data[p] >= 48: + goto st96 + } + case data[p] > 90: + switch { + case data[p] > 102: + if 103 <= data[p] && data[p] <= 122 { + goto tr81 + } + case data[p] >= 97: + goto tr169 + } + default: + goto tr81 + } + goto st0 + tr168: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st107 + st107: + if p++; p == pe { + goto _test_eof107 + } + st_case_107: +//line parser.go:4947 + switch data[p] { + case 35: + goto tr64 + case 47: + goto tr66 + case 58: + goto st5 + case 63: + goto tr67 + case 92: + goto tr66 + } + switch { + case data[p] < 71: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 70 { + goto tr169 + } + case data[p] >= 48: + goto st96 + } + case data[p] > 90: + switch { + case data[p] > 102: + if 103 <= data[p] && data[p] <= 122 { + goto tr81 + } + case data[p] >= 97: + goto tr169 + } + default: + goto tr81 + } + goto st0 + st108: + if p++; p == pe { + goto _test_eof108 + } + st_case_108: + switch data[p] { + case 33: + goto tr170 + case 35: + goto tr64 + case 37: + goto tr171 + case 47: + goto tr66 + case 58: + goto st84 + case 60: + goto st57 + case 62: + goto st57 + case 63: + goto tr67 + case 64: + goto st89 + case 91: + goto tr173 + case 92: + goto tr80 + case 95: + goto tr170 + case 126: + goto tr170 + } + switch { + case data[p] < 65: + switch { + case data[p] > 34: + if 36 <= data[p] && data[p] <= 61 { + goto tr170 + } + case data[p] >= 32: + goto st57 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 93 <= data[p] && data[p] <= 96 { + goto st57 + } + case data[p] > 122: + if 123 <= data[p] && data[p] <= 125 { + goto st57 + } + default: + goto tr172 + } + default: + goto tr172 + } + goto st0 + tr173: +//line parser.rl:23 + + host_mark = p + + goto st109 + st109: + if p++; p == pe { + goto _test_eof109 + } + st_case_109: +//line parser.go:5054 + switch data[p] { + case 35: + goto tr64 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr66 + case 118: + goto tr175 + } + switch { + case data[p] < 71: + switch { + case data[p] > 58: + if 65 <= data[p] && data[p] <= 70 { + goto tr174 + } + case data[p] >= 48: + goto st13 + } + case data[p] > 90: + switch { + case data[p] > 102: + if 103 <= data[p] && data[p] <= 122 { + goto tr81 + } + case data[p] >= 97: + goto tr174 + } + default: + goto tr81 + } + goto st0 + tr174: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st39 + st39: + if p++; p == pe { + goto _test_eof39 + } + st_case_39: +//line parser.go:5105 + switch data[p] { + case 58: + goto st40 + case 93: + goto st85 + } + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st14 + } + case data[p] > 70: + if 97 <= data[p] && data[p] <= 102 { + goto st13 + } + default: + goto st13 + } + goto st0 + st40: + if p++; p == pe { + goto _test_eof40 + } + st_case_40: + switch data[p] { + case 47: + goto st49 + case 58: + goto st13 + case 92: + goto st49 + case 93: + goto st85 + } + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st14 + } + case data[p] > 70: + if 97 <= data[p] && data[p] <= 102 { + goto st13 + } + default: + goto st13 + } + goto st0 + tr175: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st41 + st41: + if p++; p == pe { + goto _test_eof41 + } + st_case_41: +//line parser.go:5168 + if data[p] == 58 { + goto st5 + } + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st29 + } + case data[p] > 70: + if 97 <= data[p] && data[p] <= 102 { + goto st29 + } + default: + goto st29 + } + goto st0 + tr192: +//line parser.rl:23 + + host_mark = p + + goto st110 + st110: + if p++; p == pe { + goto _test_eof110 + } + st_case_110: +//line parser.go:5196 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st61 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr77 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st56 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr177 + } + case data[p] >= 58: + goto st56 + } + default: + goto st111 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st56 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st56 + } + case data[p] >= 103: + goto tr76 + } + default: + goto tr177 + } + default: + goto tr76 + } + goto st0 + tr177: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st111 + st111: + if p++; p == pe { + goto _test_eof111 + } + st_case_111: +//line parser.go:5265 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st58 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr80 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st57 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr178 + } + case data[p] >= 58: + goto st57 + } + default: + goto st95 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st57 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st57 + } + case data[p] >= 103: + goto tr79 + } + default: + goto tr178 + } + default: + goto tr79 + } + goto st0 + st112: + if p++; p == pe { + goto _test_eof112 + } + st_case_112: + switch data[p] { + case 33: + goto tr179 + case 35: + goto tr64 + case 37: + goto tr180 + case 47: + goto tr66 + case 58: + goto st83 + case 60: + goto st56 + case 62: + goto st56 + case 63: + goto tr67 + case 64: + goto st108 + case 91: + goto tr182 + case 92: + goto tr77 + case 95: + goto tr179 + case 126: + goto tr179 + } + switch { + case data[p] < 65: + switch { + case data[p] > 34: + if 36 <= data[p] && data[p] <= 61 { + goto tr179 + } + case data[p] >= 32: + goto st56 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 93 <= data[p] && data[p] <= 96 { + goto st56 + } + case data[p] > 122: + if 123 <= data[p] && data[p] <= 125 { + goto st56 + } + default: + goto tr181 + } + default: + goto tr181 + } + goto st0 + tr182: +//line parser.rl:23 + + host_mark = p + + goto st113 + st113: + if p++; p == pe { + goto _test_eof113 + } + st_case_113: +//line parser.go:5390 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st58 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr80 + case 118: + goto tr185 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st57 + } + case data[p] > 58: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr184 + } + case data[p] >= 59: + goto st57 + } + default: + goto st114 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st57 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st57 + } + case data[p] >= 103: + goto tr79 + } + default: + goto tr184 + } + default: + goto tr79 + } + goto st0 + st114: + if p++; p == pe { + goto _test_eof114 + } + st_case_114: + switch data[p] { + case 35: + goto tr64 + case 47: + goto tr66 + case 58: + goto st13 + case 63: + goto tr67 + case 92: + goto tr66 + case 93: + goto st85 + } + switch { + case data[p] < 71: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 70 { + goto tr174 + } + case data[p] >= 48: + goto st14 + } + case data[p] > 90: + switch { + case data[p] > 102: + if 103 <= data[p] && data[p] <= 122 { + goto tr81 + } + case data[p] >= 97: + goto tr174 + } + default: + goto tr81 + } + goto st0 + tr184: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st115 + st115: + if p++; p == pe { + goto _test_eof115 + } + st_case_115: +//line parser.go:5503 + switch data[p] { + case 35: + goto tr64 + case 47: + goto tr66 + case 58: + goto st40 + case 63: + goto tr67 + case 92: + goto tr66 + case 93: + goto st85 + } + switch { + case data[p] < 71: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 70 { + goto tr174 + } + case data[p] >= 48: + goto st14 + } + case data[p] > 90: + switch { + case data[p] > 102: + if 103 <= data[p] && data[p] <= 122 { + goto tr81 + } + case data[p] >= 97: + goto tr174 + } + default: + goto tr81 + } + goto st0 + tr185: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st116 + st116: + if p++; p == pe { + goto _test_eof116 + } + st_case_116: +//line parser.go:5556 + switch data[p] { + case 35: + goto tr64 + case 47: + goto tr66 + case 58: + goto st5 + case 63: + goto tr67 + case 92: + goto tr66 + } + switch { + case data[p] < 71: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 70 { + goto tr186 + } + case data[p] >= 48: + goto st29 + } + case data[p] > 90: + switch { + case data[p] > 102: + if 103 <= data[p] && data[p] <= 122 { + goto tr81 + } + case data[p] >= 97: + goto tr186 + } + default: + goto tr81 + } + goto st0 + tr186: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st42 + st42: + if p++; p == pe { + goto _test_eof42 + } + st_case_42: +//line parser.go:5607 + switch data[p] { + case 46: + goto st30 + case 58: + goto st5 + } + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st29 + } + case data[p] > 70: + if 97 <= data[p] && data[p] <= 102 { + goto st29 + } + default: + goto st29 + } + goto st0 + tr139: +//line parser.rl:23 + + host_mark = p + + goto st117 + st117: + if p++; p == pe { + goto _test_eof117 + } + st_case_117: +//line parser.go:5638 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st68 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr73 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st55 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr188 + } + case data[p] >= 58: + goto st55 + } + default: + goto st118 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st55 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st55 + } + case data[p] >= 103: + goto tr72 + } + default: + goto tr188 + } + default: + goto tr72 + } + goto st0 + tr188: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st118 + st118: + if p++; p == pe { + goto _test_eof118 + } + st_case_118: +//line parser.go:5707 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st61 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr77 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st56 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr190 + } + case data[p] >= 58: + goto st56 + } + default: + goto st94 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st56 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st56 + } + case data[p] >= 103: + goto tr76 + } + default: + goto tr190 + } + default: + goto tr76 + } + goto st0 + st119: + if p++; p == pe { + goto _test_eof119 + } + st_case_119: + switch data[p] { + case 33: + goto tr191 + case 35: + goto tr64 + case 37: + goto tr192 + case 47: + goto tr66 + case 58: + goto st82 + case 60: + goto st55 + case 62: + goto st55 + case 63: + goto tr67 + case 64: + goto st112 + case 91: + goto tr194 + case 92: + goto tr73 + case 95: + goto tr191 + case 126: + goto tr191 + } + switch { + case data[p] < 65: + switch { + case data[p] > 34: + if 36 <= data[p] && data[p] <= 61 { + goto tr191 + } + case data[p] >= 32: + goto st55 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 93 <= data[p] && data[p] <= 96 { + goto st55 + } + case data[p] > 122: + if 123 <= data[p] && data[p] <= 125 { + goto st55 + } + default: + goto tr193 + } + default: + goto tr193 + } + goto st0 + tr194: +//line parser.rl:23 + + host_mark = p + + goto st120 + st120: + if p++; p == pe { + goto _test_eof120 + } + st_case_120: +//line parser.go:5832 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st61 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr77 + case 118: + goto tr197 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st56 + } + case data[p] > 58: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr196 + } + case data[p] >= 59: + goto st56 + } + default: + goto st121 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st56 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st56 + } + case data[p] >= 103: + goto tr76 + } + default: + goto tr196 + } + default: + goto tr76 + } + goto st0 + tr196: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st121 + st121: + if p++; p == pe { + goto _test_eof121 + } + st_case_121: +//line parser.go:5903 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st58 + case 47: + goto tr66 + case 58: + goto st114 + case 63: + goto tr67 + case 92: + goto tr80 + case 93: + goto st123 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st57 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr184 + } + case data[p] >= 59: + goto st57 + } + default: + goto st122 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st57 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st57 + } + case data[p] >= 103: + goto tr79 + } + default: + goto tr184 + } + default: + goto tr79 + } + goto st0 + st122: + if p++; p == pe { + goto _test_eof122 + } + st_case_122: + switch data[p] { + case 35: + goto tr64 + case 46: + goto st15 + case 47: + goto tr66 + case 58: + goto st13 + case 63: + goto tr67 + case 92: + goto tr66 + case 93: + goto st85 + } + switch { + case data[p] < 71: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 70 { + goto tr174 + } + case data[p] >= 48: + goto st14 + } + case data[p] > 90: + switch { + case data[p] > 102: + if 103 <= data[p] && data[p] <= 122 { + goto tr81 + } + case data[p] >= 97: + goto tr174 + } + default: + goto tr81 + } + goto st0 + st123: + if p++; p == pe { + goto _test_eof123 + } + st_case_123: + switch data[p] { + case 35: + goto tr143 + case 47: + goto tr145 + case 58: + goto tr124 + case 63: + goto tr147 + case 92: + goto tr145 + } + switch { + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr200 + } + case data[p] >= 65: + goto tr200 + } + goto st0 + tr197: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st124 + st124: + if p++; p == pe { + goto _test_eof124 + } + st_case_124: +//line parser.go:6046 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st58 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr80 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st57 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr202 + } + case data[p] >= 58: + goto st57 + } + default: + goto st125 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st57 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st57 + } + case data[p] >= 103: + goto tr79 + } + default: + goto tr202 + } + default: + goto tr79 + } + goto st0 + st125: + if p++; p == pe { + goto _test_eof125 + } + st_case_125: + switch data[p] { + case 35: + goto tr64 + case 46: + goto st30 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr66 + } + switch { + case data[p] < 71: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 70 { + goto tr186 + } + case data[p] >= 48: + goto st29 + } + case data[p] > 90: + switch { + case data[p] > 102: + if 103 <= data[p] && data[p] <= 122 { + goto tr81 + } + case data[p] >= 97: + goto tr186 + } + default: + goto tr81 + } + goto st0 + tr202: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st126 + st126: + if p++; p == pe { + goto _test_eof126 + } + st_case_126: +//line parser.go:6155 + switch data[p] { + case 35: + goto tr64 + case 46: + goto st30 + case 47: + goto tr66 + case 58: + goto st5 + case 63: + goto tr67 + case 92: + goto tr66 + } + switch { + case data[p] < 71: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 70 { + goto tr186 + } + case data[p] >= 48: + goto st29 + } + case data[p] > 90: + switch { + case data[p] > 102: + if 103 <= data[p] && data[p] <= 122 { + goto tr81 + } + case data[p] >= 97: + goto tr186 + } + default: + goto tr81 + } + goto st0 + tr141: +//line parser.rl:23 + + host_mark = p + + goto st127 + st127: + if p++; p == pe { + goto _test_eof127 + } + st_case_127: +//line parser.go:6204 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st68 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr73 + case 118: + goto tr205 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st55 + } + case data[p] > 58: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr204 + } + case data[p] >= 59: + goto st55 + } + default: + goto st128 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st55 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st55 + } + case data[p] >= 103: + goto tr72 + } + default: + goto tr204 + } + default: + goto tr72 + } + goto st0 + tr204: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st128 + st128: + if p++; p == pe { + goto _test_eof128 + } + st_case_128: +//line parser.go:6275 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st61 + case 47: + goto tr66 + case 58: + goto st121 + case 63: + goto tr67 + case 92: + goto tr77 + case 93: + goto st131 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st56 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr196 + } + case data[p] >= 59: + goto st56 + } + default: + goto st129 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st56 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st56 + } + case data[p] >= 103: + goto tr76 + } + default: + goto tr196 + } + default: + goto tr76 + } + goto st0 + st129: + if p++; p == pe { + goto _test_eof129 + } + st_case_129: + switch data[p] { + case 35: + goto tr64 + case 37: + goto st58 + case 46: + goto st130 + case 47: + goto tr66 + case 58: + goto st114 + case 63: + goto tr67 + case 92: + goto tr80 + case 93: + goto st123 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 45 { + goto st57 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr184 + } + case data[p] >= 59: + goto st57 + } + default: + goto st122 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st57 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st57 + } + case data[p] >= 103: + goto tr79 + } + default: + goto tr184 + } + default: + goto tr79 + } + goto st0 + st130: + if p++; p == pe { + goto _test_eof130 + } + st_case_130: + switch data[p] { + case 35: + goto tr64 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr66 + } + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st16 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr81 + } + default: + goto tr81 + } + goto st0 + st131: + if p++; p == pe { + goto _test_eof131 + } + st_case_131: + switch data[p] { + case 35: + goto tr143 + case 37: + goto st58 + case 47: + goto tr145 + case 58: + goto tr209 + case 63: + goto tr147 + case 92: + goto tr156 + } + switch { + case data[p] < 91: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 90 { + goto tr210 + } + case data[p] >= 32: + goto st57 + } + case data[p] > 96: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st57 + } + case data[p] >= 97: + goto tr210 + } + default: + goto st57 + } + goto st0 + tr209: +//line parser.rl:27 + + u.Host = data[host_mark:p] + + goto st132 + st132: + if p++; p == pe { + goto _test_eof132 + } + st_case_132: +//line parser.go:6478 + switch data[p] { + case 35: + goto tr64 + case 37: + goto tr31 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr161 + } + switch { + case data[p] < 91: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 90 { + goto tr211 + } + case data[p] >= 32: + goto tr3 + } + case data[p] > 96: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto tr3 + } + case data[p] >= 97: + goto tr211 + } + default: + goto tr3 + } + goto st0 + tr205: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st133 + st133: + if p++; p == pe { + goto _test_eof133 + } + st_case_133: +//line parser.go:6529 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st61 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr77 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st56 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr213 + } + case data[p] >= 58: + goto st56 + } + default: + goto st134 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st56 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st56 + } + case data[p] >= 103: + goto tr76 + } + default: + goto tr213 + } + default: + goto tr76 + } + goto st0 + tr213: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st134 + st134: + if p++; p == pe { + goto _test_eof134 + } + st_case_134: +//line parser.go:6598 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st58 + case 46: + goto st135 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr80 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 45 { + goto st57 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr202 + } + case data[p] >= 58: + goto st57 + } + default: + goto st125 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st57 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st57 + } + case data[p] >= 103: + goto tr79 + } + default: + goto tr202 + } + default: + goto tr79 + } + goto st0 + st135: + if p++; p == pe { + goto _test_eof135 + } + st_case_135: + switch data[p] { + case 33: + goto st31 + case 35: + goto tr64 + case 36: + goto st31 + case 47: + goto tr66 + case 61: + goto st31 + case 63: + goto tr67 + case 92: + goto tr66 + case 95: + goto st31 + case 126: + goto st31 + } + switch { + case data[p] < 65: + if 38 <= data[p] && data[p] <= 59 { + goto st31 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr215 + } + default: + goto tr215 + } + goto st0 + tr215: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st43 + st43: + if p++; p == pe { + goto _test_eof43 + } + st_case_43: +//line parser.go:6707 + switch data[p] { + case 33: + goto st31 + case 36: + goto st31 + case 58: + goto st44 + case 61: + goto st31 + case 93: + goto st85 + case 95: + goto st31 + case 126: + goto st31 + } + switch { + case data[p] < 48: + if 38 <= data[p] && data[p] <= 46 { + goto st31 + } + case data[p] > 59: + switch { + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto st31 + } + case data[p] >= 65: + goto st31 + } + default: + goto st31 + } + goto st0 + st44: + if p++; p == pe { + goto _test_eof44 + } + st_case_44: + switch data[p] { + case 33: + goto st31 + case 36: + goto st31 + case 47: + goto st49 + case 61: + goto st31 + case 92: + goto st49 + case 93: + goto st85 + case 95: + goto st31 + case 126: + goto st31 + } + switch { + case data[p] < 65: + if 38 <= data[p] && data[p] <= 59 { + goto st31 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto st31 + } + default: + goto st31 + } + goto st0 + tr122: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st136 + st136: + if p++; p == pe { + goto _test_eof136 + } + st_case_136: +//line parser.go:6793 + switch data[p] { + case 33: + goto st8 + case 35: + goto tr64 + case 37: + goto st9 + case 47: + goto tr66 + case 58: + goto st33 + case 61: + goto st8 + case 63: + goto tr67 + case 64: + goto st11 + case 92: + goto tr66 + case 95: + goto st8 + case 126: + goto st8 + } + switch { + case data[p] < 65: + if 36 <= data[p] && data[p] <= 59 { + goto st8 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr123 + } + default: + goto tr123 + } + goto st0 + st137: + if p++; p == pe { + goto _test_eof137 + } + st_case_137: + switch data[p] { + case 35: + goto tr64 + case 37: + goto st58 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr80 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st57 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr217 + } + case data[p] >= 58: + goto st57 + } + default: + goto st138 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st57 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st57 + } + case data[p] >= 103: + goto tr79 + } + default: + goto tr217 + } + default: + goto tr79 + } + goto st0 + st138: + if p++; p == pe { + goto _test_eof138 + } + st_case_138: + switch data[p] { + case 35: + goto tr64 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr66 + } + switch { + case data[p] < 71: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 70 { + goto tr119 + } + case data[p] >= 48: + goto st83 + } + case data[p] > 90: + switch { + case data[p] > 102: + if 103 <= data[p] && data[p] <= 122 { + goto tr81 + } + case data[p] >= 97: + goto tr119 + } + default: + goto tr81 + } + goto st0 + tr217: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st139 + st139: + if p++; p == pe { + goto _test_eof139 + } + st_case_139: +//line parser.go:6942 + switch data[p] { + case 35: + goto tr64 + case 47: + goto tr66 + case 58: + goto st5 + case 63: + goto tr67 + case 92: + goto tr66 + } + switch { + case data[p] < 71: + switch { + case data[p] > 57: + if 65 <= data[p] && data[p] <= 70 { + goto tr119 + } + case data[p] >= 48: + goto st83 + } + case data[p] > 90: + switch { + case data[p] > 102: + if 103 <= data[p] && data[p] <= 122 { + goto tr81 + } + case data[p] >= 97: + goto tr119 + } + default: + goto tr81 + } + goto st0 + st140: + if p++; p == pe { + goto _test_eof140 + } + st_case_140: + switch data[p] { + case 35: + goto tr64 + case 37: + goto st61 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr77 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st56 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr219 + } + case data[p] >= 58: + goto st56 + } + default: + goto st141 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st56 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st56 + } + case data[p] >= 103: + goto tr76 + } + default: + goto tr219 + } + default: + goto tr76 + } + goto st0 + tr219: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st141 + st141: + if p++; p == pe { + goto _test_eof141 + } + st_case_141: +//line parser.go:7051 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st58 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr80 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st57 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr115 + } + case data[p] >= 58: + goto st57 + } + default: + goto st82 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st57 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st57 + } + case data[p] >= 103: + goto tr79 + } + default: + goto tr115 + } + default: + goto tr79 + } + goto st0 + st142: + if p++; p == pe { + goto _test_eof142 + } + st_case_142: + switch data[p] { + case 35: + goto tr64 + case 37: + goto st68 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr73 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st55 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr221 + } + case data[p] >= 58: + goto st55 + } + default: + goto st143 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st55 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st55 + } + case data[p] >= 103: + goto tr72 + } + default: + goto tr221 + } + default: + goto tr72 + } + goto st0 + tr221: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st143 + st143: + if p++; p == pe { + goto _test_eof143 + } + st_case_143: +//line parser.go:7178 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st61 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr77 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st56 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr111 + } + case data[p] >= 58: + goto st56 + } + default: + goto st81 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st56 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st56 + } + case data[p] >= 103: + goto tr76 + } + default: + goto tr111 + } + default: + goto tr76 + } + goto st0 + tr44: +//line parser.rl:10 + mark = p + goto st144 + tr230: +//line parser.rl:19 + + u.Protocol = data[0 : p-1] + +//line parser.rl:10 + mark = p + goto st144 + st144: + if p++; p == pe { + goto _test_eof144 + } + st_case_144: +//line parser.go:7249 + switch data[p] { + case 35: + goto tr57 + case 47: + goto st145 + case 63: + goto tr58 + } + if 32 <= data[p] && data[p] <= 126 { + goto st50 + } + goto st0 + st145: + if p++; p == pe { + goto _test_eof145 + } + st_case_145: + switch data[p] { + case 33: + goto tr14 + case 35: + goto st47 + case 37: + goto tr15 + case 47: + goto tr47 + case 58: + goto st8 + case 61: + goto tr14 + case 63: + goto st51 + case 64: + goto st11 + case 91: + goto tr16 + case 92: + goto tr47 + case 95: + goto tr14 + case 126: + goto tr14 + } + switch { + case data[p] < 65: + if 36 <= data[p] && data[p] <= 59 { + goto tr14 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr223 + } + default: + goto tr223 + } + goto st0 + tr46: +//line parser.rl:10 + mark = p +//line parser.rl:23 + + host_mark = p + + goto st146 + tr226: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:10 + mark = p + goto st146 + st146: + if p++; p == pe { + goto _test_eof146 + } + st_case_146: +//line parser.go:7327 + switch data[p] { + case 33: + goto st46 + case 35: + goto tr48 + case 37: + goto st1 + case 43: + goto st146 + case 47: + goto tr50 + case 58: + goto tr225 + case 59: + goto st46 + case 61: + goto st46 + case 63: + goto tr52 + case 64: + goto st11 + case 92: + goto tr50 + case 95: + goto st46 + case 126: + goto st46 + } + switch { + case data[p] < 45: + if 36 <= data[p] && data[p] <= 44 { + goto st46 + } + case data[p] > 57: + switch { + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr226 + } + case data[p] >= 65: + goto tr226 + } + default: + goto st146 + } + goto st0 + tr225: +//line parser.rl:27 + + u.Host = data[host_mark:p] + + goto st147 + st147: + if p++; p == pe { + goto _test_eof147 + } + st_case_147: +//line parser.go:7385 + switch data[p] { + case 33: + goto tr227 + case 35: + goto tr228 + case 37: + goto tr229 + case 47: + goto tr230 + case 58: + goto tr231 + case 60: + goto tr3 + case 62: + goto tr3 + case 63: + goto tr232 + case 64: + goto tr233 + case 91: + goto tr235 + case 92: + goto tr236 + case 95: + goto tr227 + case 126: + goto tr227 + } + switch { + case data[p] < 65: + switch { + case data[p] > 34: + if 36 <= data[p] && data[p] <= 61 { + goto tr227 + } + case data[p] >= 32: + goto tr3 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 93 <= data[p] && data[p] <= 96 { + goto tr3 + } + case data[p] > 122: + if 123 <= data[p] && data[p] <= 125 { + goto tr3 + } + default: + goto tr234 + } + default: + goto tr234 + } + goto st0 + tr243: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st148 + tr227: +//line parser.rl:19 + + u.Protocol = data[0 : p-1] + +//line parser.rl:23 + + host_mark = p + +//line parser.rl:11 + port_mark = p + goto st148 + tr234: +//line parser.rl:19 + + u.Protocol = data[0 : p-1] + +//line parser.rl:23 + + host_mark = p + +//line parser.rl:11 + port_mark = p +//line parser.rl:10 + mark = p + goto st148 + st148: + if p++; p == pe { + goto _test_eof148 + } + st_case_148: +//line parser.go:7482 + switch data[p] { + case 33: + goto st94 + case 35: + goto tr143 + case 37: + goto st117 + case 47: + goto tr145 + case 58: + goto tr146 + case 60: + goto st54 + case 62: + goto st54 + case 63: + goto tr147 + case 64: + goto st119 + case 92: + goto tr239 + case 95: + goto st94 + case 126: + goto st94 + } + switch { + case data[p] < 65: + switch { + case data[p] > 34: + if 36 <= data[p] && data[p] <= 61 { + goto st94 + } + case data[p] >= 32: + goto st54 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st54 + } + case data[p] > 122: + if 123 <= data[p] && data[p] <= 125 { + goto st54 + } + default: + goto tr238 + } + default: + goto tr238 + } + goto st0 + tr229: +//line parser.rl:19 + + u.Protocol = data[0 : p-1] + +//line parser.rl:23 + + host_mark = p + +//line parser.rl:11 + port_mark = p + goto st149 + st149: + if p++; p == pe { + goto _test_eof149 + } + st_case_149: +//line parser.go:7553 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st74 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr69 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st54 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr241 + } + case data[p] >= 58: + goto st54 + } + default: + goto st150 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st54 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st54 + } + case data[p] >= 103: + goto tr68 + } + default: + goto tr241 + } + default: + goto tr68 + } + goto st0 + tr241: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st150 + st150: + if p++; p == pe { + goto _test_eof150 + } + st_case_150: +//line parser.go:7622 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st68 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr73 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st55 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr243 + } + case data[p] >= 58: + goto st55 + } + default: + goto st148 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st55 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st55 + } + case data[p] >= 103: + goto tr72 + } + default: + goto tr243 + } + default: + goto tr72 + } + goto st0 + tr235: +//line parser.rl:19 + + u.Protocol = data[0 : p-1] + +//line parser.rl:23 + + host_mark = p + +//line parser.rl:11 + port_mark = p + goto st151 + st151: + if p++; p == pe { + goto _test_eof151 + } + st_case_151: +//line parser.go:7693 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st74 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr69 + case 118: + goto tr246 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st54 + } + case data[p] > 58: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr245 + } + case data[p] >= 59: + goto st54 + } + default: + goto st152 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st54 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st54 + } + case data[p] >= 103: + goto tr68 + } + default: + goto tr245 + } + default: + goto tr68 + } + goto st0 + tr245: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st152 + st152: + if p++; p == pe { + goto _test_eof152 + } + st_case_152: +//line parser.go:7764 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st68 + case 47: + goto tr66 + case 58: + goto st128 + case 63: + goto tr67 + case 92: + goto tr73 + case 93: + goto st156 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st55 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr204 + } + case data[p] >= 59: + goto st55 + } + default: + goto st153 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st55 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st55 + } + case data[p] >= 103: + goto tr72 + } + default: + goto tr204 + } + default: + goto tr72 + } + goto st0 + st153: + if p++; p == pe { + goto _test_eof153 + } + st_case_153: + switch data[p] { + case 35: + goto tr64 + case 37: + goto st61 + case 46: + goto st154 + case 47: + goto tr66 + case 58: + goto st121 + case 63: + goto tr67 + case 92: + goto tr77 + case 93: + goto st131 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 45 { + goto st56 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr196 + } + case data[p] >= 59: + goto st56 + } + default: + goto st129 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st56 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st56 + } + case data[p] >= 103: + goto tr76 + } + default: + goto tr196 + } + default: + goto tr76 + } + goto st0 + st154: + if p++; p == pe { + goto _test_eof154 + } + st_case_154: + switch data[p] { + case 35: + goto tr64 + case 37: + goto st58 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr80 + } + switch { + case data[p] < 65: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st57 + } + case data[p] > 57: + if 58 <= data[p] && data[p] <= 64 { + goto st57 + } + default: + goto st155 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st57 + } + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st57 + } + default: + goto tr79 + } + default: + goto tr79 + } + goto st0 + st155: + if p++; p == pe { + goto _test_eof155 + } + st_case_155: + switch data[p] { + case 35: + goto tr64 + case 46: + goto st17 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr66 + } + switch { + case data[p] < 65: + if 48 <= data[p] && data[p] <= 57 { + goto st26 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr81 + } + default: + goto tr81 + } + goto st0 + st156: + if p++; p == pe { + goto _test_eof156 + } + st_case_156: + switch data[p] { + case 35: + goto tr143 + case 37: + goto st61 + case 47: + goto tr145 + case 58: + goto tr209 + case 63: + goto tr147 + case 92: + goto tr153 + } + switch { + case data[p] < 91: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 90 { + goto tr251 + } + case data[p] >= 32: + goto st56 + } + case data[p] > 96: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st56 + } + case data[p] >= 97: + goto tr251 + } + default: + goto st56 + } + goto st0 + tr246: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st157 + st157: + if p++; p == pe { + goto _test_eof157 + } + st_case_157: +//line parser.go:8021 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st68 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr73 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 46 { + goto st55 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr253 + } + case data[p] >= 58: + goto st55 + } + default: + goto st158 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st55 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st55 + } + case data[p] >= 103: + goto tr72 + } + default: + goto tr253 + } + default: + goto tr72 + } + goto st0 + tr253: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st158 + st158: + if p++; p == pe { + goto _test_eof158 + } + st_case_158: +//line parser.go:8090 + switch data[p] { + case 35: + goto tr64 + case 37: + goto st61 + case 46: + goto st159 + case 47: + goto tr66 + case 63: + goto tr67 + case 92: + goto tr77 + } + switch { + case data[p] < 71: + switch { + case data[p] < 48: + if 32 <= data[p] && data[p] <= 45 { + goto st56 + } + case data[p] > 57: + switch { + case data[p] > 64: + if 65 <= data[p] && data[p] <= 70 { + goto tr213 + } + case data[p] >= 58: + goto st56 + } + default: + goto st134 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st56 + } + case data[p] > 102: + switch { + case data[p] > 122: + if 123 <= data[p] && data[p] <= 126 { + goto st56 + } + case data[p] >= 103: + goto tr76 + } + default: + goto tr213 + } + default: + goto tr76 + } + goto st0 + st159: + if p++; p == pe { + goto _test_eof159 + } + st_case_159: + switch data[p] { + case 33: + goto st160 + case 35: + goto tr64 + case 37: + goto st58 + case 47: + goto tr66 + case 60: + goto st57 + case 63: + goto tr67 + case 92: + goto tr80 + case 95: + goto st160 + case 126: + goto st160 + } + switch { + case data[p] < 65: + switch { + case data[p] < 36: + if 32 <= data[p] && data[p] <= 34 { + goto st57 + } + case data[p] > 61: + if 62 <= data[p] && data[p] <= 64 { + goto st57 + } + default: + goto st160 + } + case data[p] > 90: + switch { + case data[p] < 97: + if 91 <= data[p] && data[p] <= 96 { + goto st57 + } + case data[p] > 122: + if 123 <= data[p] && data[p] <= 125 { + goto st57 + } + default: + goto tr256 + } + default: + goto tr256 + } + goto st0 + st160: + if p++; p == pe { + goto _test_eof160 + } + st_case_160: + switch data[p] { + case 33: + goto st31 + case 35: + goto tr64 + case 36: + goto st31 + case 47: + goto tr66 + case 61: + goto st31 + case 63: + goto tr67 + case 92: + goto tr66 + case 93: + goto st85 + case 95: + goto st31 + case 126: + goto st31 + } + switch { + case data[p] < 65: + if 38 <= data[p] && data[p] <= 59 { + goto st31 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr215 + } + default: + goto tr215 + } + goto st0 + tr256: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:10 + mark = p + goto st161 + st161: + if p++; p == pe { + goto _test_eof161 + } + st_case_161: +//line parser.go:8257 + switch data[p] { + case 33: + goto st31 + case 35: + goto tr64 + case 36: + goto st31 + case 47: + goto tr66 + case 58: + goto st44 + case 61: + goto st31 + case 63: + goto tr67 + case 92: + goto tr66 + case 93: + goto st85 + case 95: + goto st31 + case 126: + goto st31 + } + switch { + case data[p] < 65: + if 38 <= data[p] && data[p] <= 59 { + goto st31 + } + case data[p] > 90: + if 97 <= data[p] && data[p] <= 122 { + goto tr215 + } + default: + goto tr215 + } + goto st0 + st_out: + _test_eof46: + cs = 46 + goto _test_eof + _test_eof47: + cs = 47 + goto _test_eof + _test_eof48: + cs = 48 + goto _test_eof + _test_eof1: + cs = 1 + goto _test_eof + _test_eof2: + cs = 2 + goto _test_eof + _test_eof49: + cs = 49 + goto _test_eof + _test_eof50: + cs = 50 + goto _test_eof + _test_eof51: + cs = 51 + goto _test_eof + _test_eof52: + cs = 52 + goto _test_eof + _test_eof3: + cs = 3 + goto _test_eof + _test_eof53: + cs = 53 + goto _test_eof + _test_eof54: + cs = 54 + goto _test_eof + _test_eof55: + cs = 55 + goto _test_eof + _test_eof56: + cs = 56 + goto _test_eof + _test_eof57: + cs = 57 + goto _test_eof + _test_eof4: + cs = 4 + goto _test_eof + _test_eof5: + cs = 5 + goto _test_eof + _test_eof58: + cs = 58 + goto _test_eof + _test_eof6: + cs = 6 + goto _test_eof + _test_eof7: + cs = 7 + goto _test_eof + _test_eof59: + cs = 59 + goto _test_eof + _test_eof60: + cs = 60 + goto _test_eof + _test_eof61: + cs = 61 + goto _test_eof + _test_eof62: + cs = 62 + goto _test_eof + _test_eof63: + cs = 63 + goto _test_eof + _test_eof64: + cs = 64 + goto _test_eof + _test_eof65: + cs = 65 + goto _test_eof + _test_eof66: + cs = 66 + goto _test_eof + _test_eof67: + cs = 67 + goto _test_eof + _test_eof68: + cs = 68 + goto _test_eof + _test_eof69: + cs = 69 + goto _test_eof + _test_eof70: + cs = 70 + goto _test_eof + _test_eof71: + cs = 71 + goto _test_eof + _test_eof72: + cs = 72 + goto _test_eof + _test_eof73: + cs = 73 + goto _test_eof + _test_eof74: + cs = 74 + goto _test_eof + _test_eof75: + cs = 75 + goto _test_eof + _test_eof76: + cs = 76 + goto _test_eof + _test_eof77: + cs = 77 + goto _test_eof + _test_eof78: + cs = 78 + goto _test_eof + _test_eof79: + cs = 79 + goto _test_eof + _test_eof80: + cs = 80 + goto _test_eof + _test_eof81: + cs = 81 + goto _test_eof + _test_eof82: + cs = 82 + goto _test_eof + _test_eof83: + cs = 83 + goto _test_eof + _test_eof84: + cs = 84 + goto _test_eof + _test_eof8: + cs = 8 + goto _test_eof + _test_eof9: + cs = 9 + goto _test_eof + _test_eof10: + cs = 10 + goto _test_eof + _test_eof11: + cs = 11 + goto _test_eof + _test_eof12: + cs = 12 + goto _test_eof + _test_eof13: + cs = 13 + goto _test_eof + _test_eof14: + cs = 14 + goto _test_eof + _test_eof15: + cs = 15 + goto _test_eof + _test_eof16: + cs = 16 + goto _test_eof + _test_eof17: + cs = 17 + goto _test_eof + _test_eof18: + cs = 18 + goto _test_eof + _test_eof19: + cs = 19 + goto _test_eof + _test_eof20: + cs = 20 + goto _test_eof + _test_eof21: + cs = 21 + goto _test_eof + _test_eof22: + cs = 22 + goto _test_eof + _test_eof85: + cs = 85 + goto _test_eof + _test_eof23: + cs = 23 + goto _test_eof + _test_eof86: + cs = 86 + goto _test_eof + _test_eof87: + cs = 87 + goto _test_eof + _test_eof24: + cs = 24 + goto _test_eof + _test_eof25: + cs = 25 + goto _test_eof + _test_eof26: + cs = 26 + goto _test_eof + _test_eof27: + cs = 27 + goto _test_eof + _test_eof28: + cs = 28 + goto _test_eof + _test_eof29: + cs = 29 + goto _test_eof + _test_eof30: + cs = 30 + goto _test_eof + _test_eof31: + cs = 31 + goto _test_eof + _test_eof32: + cs = 32 + goto _test_eof + _test_eof33: + cs = 33 + goto _test_eof + _test_eof88: + cs = 88 + goto _test_eof + _test_eof34: + cs = 34 + goto _test_eof + _test_eof35: + cs = 35 + goto _test_eof + _test_eof89: + cs = 89 + goto _test_eof + _test_eof90: + cs = 90 + goto _test_eof + _test_eof36: + cs = 36 + goto _test_eof + _test_eof91: + cs = 91 + goto _test_eof + _test_eof92: + cs = 92 + goto _test_eof + _test_eof93: + cs = 93 + goto _test_eof + _test_eof94: + cs = 94 + goto _test_eof + _test_eof95: + cs = 95 + goto _test_eof + _test_eof96: + cs = 96 + goto _test_eof + _test_eof97: + cs = 97 + goto _test_eof + _test_eof98: + cs = 98 + goto _test_eof + _test_eof37: + cs = 37 + goto _test_eof + _test_eof38: + cs = 38 + goto _test_eof + _test_eof99: + cs = 99 + goto _test_eof + _test_eof100: + cs = 100 + goto _test_eof + _test_eof101: + cs = 101 + goto _test_eof + _test_eof102: + cs = 102 + goto _test_eof + _test_eof103: + cs = 103 + goto _test_eof + _test_eof104: + cs = 104 + goto _test_eof + _test_eof105: + cs = 105 + goto _test_eof + _test_eof106: + cs = 106 + goto _test_eof + _test_eof107: + cs = 107 + goto _test_eof + _test_eof108: + cs = 108 + goto _test_eof + _test_eof109: + cs = 109 + goto _test_eof + _test_eof39: + cs = 39 + goto _test_eof + _test_eof40: + cs = 40 + goto _test_eof + _test_eof41: + cs = 41 + goto _test_eof + _test_eof110: + cs = 110 + goto _test_eof + _test_eof111: + cs = 111 + goto _test_eof + _test_eof112: + cs = 112 + goto _test_eof + _test_eof113: + cs = 113 + goto _test_eof + _test_eof114: + cs = 114 + goto _test_eof + _test_eof115: + cs = 115 + goto _test_eof + _test_eof116: + cs = 116 + goto _test_eof + _test_eof42: + cs = 42 + goto _test_eof + _test_eof117: + cs = 117 + goto _test_eof + _test_eof118: + cs = 118 + goto _test_eof + _test_eof119: + cs = 119 + goto _test_eof + _test_eof120: + cs = 120 + goto _test_eof + _test_eof121: + cs = 121 + goto _test_eof + _test_eof122: + cs = 122 + goto _test_eof + _test_eof123: + cs = 123 + goto _test_eof + _test_eof124: + cs = 124 + goto _test_eof + _test_eof125: + cs = 125 + goto _test_eof + _test_eof126: + cs = 126 + goto _test_eof + _test_eof127: + cs = 127 + goto _test_eof + _test_eof128: + cs = 128 + goto _test_eof + _test_eof129: + cs = 129 + goto _test_eof + _test_eof130: + cs = 130 + goto _test_eof + _test_eof131: + cs = 131 + goto _test_eof + _test_eof132: + cs = 132 + goto _test_eof + _test_eof133: + cs = 133 + goto _test_eof + _test_eof134: + cs = 134 + goto _test_eof + _test_eof135: + cs = 135 + goto _test_eof + _test_eof43: + cs = 43 + goto _test_eof + _test_eof44: + cs = 44 + goto _test_eof + _test_eof136: + cs = 136 + goto _test_eof + _test_eof137: + cs = 137 + goto _test_eof + _test_eof138: + cs = 138 + goto _test_eof + _test_eof139: + cs = 139 + goto _test_eof + _test_eof140: + cs = 140 + goto _test_eof + _test_eof141: + cs = 141 + goto _test_eof + _test_eof142: + cs = 142 + goto _test_eof + _test_eof143: + cs = 143 + goto _test_eof + _test_eof144: + cs = 144 + goto _test_eof + _test_eof145: + cs = 145 + goto _test_eof + _test_eof146: + cs = 146 + goto _test_eof + _test_eof147: + cs = 147 + goto _test_eof + _test_eof148: + cs = 148 + goto _test_eof + _test_eof149: + cs = 149 + goto _test_eof + _test_eof150: + cs = 150 + goto _test_eof + _test_eof151: + cs = 151 + goto _test_eof + _test_eof152: + cs = 152 + goto _test_eof + _test_eof153: + cs = 153 + goto _test_eof + _test_eof154: + cs = 154 + goto _test_eof + _test_eof155: + cs = 155 + goto _test_eof + _test_eof156: + cs = 156 + goto _test_eof + _test_eof157: + cs = 157 + goto _test_eof + _test_eof158: + cs = 158 + goto _test_eof + _test_eof159: + cs = 159 + goto _test_eof + _test_eof160: + cs = 160 + goto _test_eof + _test_eof161: + cs = 161 + goto _test_eof + + _test_eof: + { + } + if p == eof { + switch cs { + case 53, 54, 55, 56, 57, 58, 59, 61, 62, 63, 68, 69, 74, 75, 80, 81, 82, 83, 84, 86, 87, 88, 89, 91, 92, 93, 98, 99, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 124, 125, 126, 127, 128, 129, 130, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 149, 150, 151, 152, 153, 154, 155, 157, 158, 159, 160, 161: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + + case 147: +//line parser.rl:19 + + u.Protocol = data[0 : p-1] + + case 46, 85, 90, 146: +//line parser.rl:27 + + u.Host = data[host_mark:p] + + case 52: +//line parser.rl:31 + + if u.Query == "" { + u.Query = data[mark:p] + } + + case 49, 50, 67, 144: +//line parser.rl:37 + + if u.Path == "" { + u.Path = data[mark:p] + } + + case 48: +//line parser.rl:43 + + u.Fragment = data[mark:p] + + case 51: +//line parser.rl:10 + mark = p +//line parser.rl:31 + + if u.Query == "" { + u.Query = data[mark:p] + } + + case 47: +//line parser.rl:10 + mark = p +//line parser.rl:43 + + u.Fragment = data[mark:p] + + case 60, 64, 65, 66, 70, 71, 72, 73, 76, 77, 78, 79, 100, 101, 102, 103: +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.rl:37 + + if u.Path == "" { + u.Path = data[mark:p] + } + + case 94, 95, 96, 97, 104, 123, 131, 148, 156: +//line parser.rl:27 + + u.Host = data[host_mark:p] + +//line parser.rl:13 + + if port_mark > host_mark { + u.Port = data[port_mark:p] + } + +//line parser.go:8536 + } + } + + _out: + { + } + } + +//line parser.rl:116 + if cs < url_parser_first_final { + return nil, fmt.Errorf("Failed to match URL") + } else { + return u, nil + } +} diff --git a/vendor/github.com/ImVexed/fasturl/parser.rl b/vendor/github.com/ImVexed/fasturl/parser.rl new file mode 100644 index 00000000..963abe2d --- /dev/null +++ b/vendor/github.com/ImVexed/fasturl/parser.rl @@ -0,0 +1,122 @@ +// Package fasturl is a Go URL parser using a [Ragel](http://www.colm.net/open-source/ragel/) state-machine instead of regex, or the built in standard library `url.Parse`. +// +package fasturl + +import "fmt" + +%%{ + machine url_parser; + + action mark { mark = fpc } + action mark_port { port_mark = fpc } + + action save_port { + if port_mark > host_mark{ + u.Port = data[port_mark:fpc] + } + } + + action save_scheme { + u.Protocol = data[0:fpc-1] + } + + action mark_host { + host_mark = fpc; + } + + action save_host { + u.Host = data[host_mark:fpc] + } + + action save_query { + if u.Query == "" { + u.Query = data[mark:fpc] + } + } + + action save_path { + if u.Path == "" { + u.Path = data[mark:fpc] + } + } + + action save_fragment { + u.Fragment = data[mark:fpc] + } + + pct_encoded = "%" xdigit xdigit; + + gen_delims = ":" | "/" | "?" | "#" | "[" | "]" | "@"; + sub_delims = "!" | "$" | "&" | "'" | "(" | ")" | "*" | "+" | "," | ";" | "="; + + reserved = gen_delims | sub_delims; + unreserved = alpha | digit | "-" | "." | "_" | "~"; + + # many clients don't encode these, e.g. curl, wget, ... + delims = "<" | ">" | "%" | "#" | '"'; + unwise = " " | "{" | "}" | "|" | "\\" | "^" | "[" | "]" | "`"; + + pchar = unreserved | pct_encoded | sub_delims | ":" | "@" | delims | unwise; + slash = "/" | "\\"; + path = (slash ( (pchar - ("?" | "#")) + ( slash (pchar - ("?" | "#"))* )* )? ) >mark %save_path; + drivepath = ( (slash|(alpha ":" slash)) ( (pchar - ("?" | "#")) + ( slash (pchar - ("?" | "#"))* )* )? ) >mark %save_path; + scheme = (alpha ( alpha | digit | "+" | "-" | "." )*); + + #simple ipv4 address + dec_octet = digit{1,3}; + IPv4address = dec_octet "." dec_octet "." dec_octet "." dec_octet; + + IPvFuture = "v" xdigit+ "." ( unreserved | sub_delims | ":" )+; + + # simple ipv6 address + IPv6address = (":" | xdigit)+ IPv4address?; + + IP_literal = "[" ( IPv6address | IPvFuture ) "]"; + + reg_name = ( unreserved | pct_encoded | sub_delims )+; + + userinfo = ( unreserved | pct_encoded | sub_delims | ":" | "@" )*; + host = IP_literal | IPv4address | reg_name; + port = (pchar - ("/" | "?" | "#")){1,5} ; + authority = ( userinfo "@" )? (host >mark_host %save_host) ( ":" port >mark_port %save_port)?; + + fragment = ( pchar | "/" | "?" )* >mark %save_fragment; + query = (pchar - "#")* >mark %save_query; + + full_ref = drivepath? ( "?" query )? ( "#" fragment )?; + relative_ref = path? ( "?" query )? ( "#" fragment )?; + absolute_hier_part = ("//")? authority? full_ref?; + hier_part = ("//")? authority? relative_ref?; + + absolute_URI = ((scheme ":") >mark %save_scheme)? absolute_hier_part; + URI = absolute_URI | relative_ref; + main := URI; + + write data; +}%% + +// URL represents the different parts of a parsed URL +type URL struct { + Protocol string + Host string + Port string + Path string + Query string + Fragment string +} + +// ParseURL parses a given URL and returns a `URL` representing the different parts +func ParseURL(data string) (*URL, error){ + mark, host_mark, port_mark, cs, p, pe, eof := 0, 0, 0, url_parser_en_main, 0, len(data), len(data) + + u := &URL{} + + %% write init; + %% write exec; + if cs < url_parser_first_final { + return nil, fmt.Errorf("Failed to match URL") + } else { + return u, nil + } +} + diff --git a/vendor/github.com/ImVexed/fasturl/parser_fuzz.go b/vendor/github.com/ImVexed/fasturl/parser_fuzz.go new file mode 100644 index 00000000..236ce17d --- /dev/null +++ b/vendor/github.com/ImVexed/fasturl/parser_fuzz.go @@ -0,0 +1,10 @@ +// +build gofuzz + +package fasturl + +func Fuzz(data []byte) int { + if _, err := ParseURL(string(data)); err != nil { + return 0 + } + return 1 +} diff --git a/vendor/github.com/ImVexed/fasturl/readme.md b/vendor/github.com/ImVexed/fasturl/readme.md new file mode 100644 index 00000000..c9366762 --- /dev/null +++ b/vendor/github.com/ImVexed/fasturl/readme.md @@ -0,0 +1,36 @@ + + + +## Fast URL +FastURL is a Go URL parser using a [Ragel](http://www.colm.net/open-source/ragel/) state-machine instead of regex, or the built in standard library `url.Parse`. + +## Why? +*S P E E D* + +## Examples +See our [tests](https://github.com/ImVexed/fasturl/blob/master/parser_test.go#L45) +## Benchmarks +## ns/op +![](/_images/ns.svg) +## B/op +![](/_images/b.svg) + +## Raw: +``` +goos: linux +goarch: amd64 +pkg: github.com/ImVexed/fasturl +BenchmarkRegex-32 464509 2557 ns/op 530 B/op 3 allocs/op +BenchmarkRagel-32 5350304 225 ns/op 96 B/op 1 allocs/op +BenchmarkStd-32 2225313 537 ns/op 128 B/op 1 allocs/op +PASS +ok github.com/ImVexed/fasturl 4.405s +``` + +## How does this work? +Lots of goto's and determinism, feel free to zoom +![](/_images/graph.svg) + + +## Credits +[maximecaron](https://github.com/maximecaron) - Creating the initial ragael parser diff --git a/vendor/github.com/btcsuite/btcd/btcec/v2/LICENSE b/vendor/github.com/btcsuite/btcd/btcec/v2/LICENSE new file mode 100644 index 00000000..46dcd395 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcec/v2/LICENSE @@ -0,0 +1,16 @@ +ISC License + +Copyright (c) 2013-2023 The btcsuite developers +Copyright (c) 2015-2016 The Decred developers + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/btcsuite/btcd/btcec/v2/README.md b/vendor/github.com/btcsuite/btcd/btcec/v2/README.md new file mode 100644 index 00000000..53391773 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcec/v2/README.md @@ -0,0 +1,40 @@ +btcec +===== + +[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) +[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) +[![GoDoc](https://pkg.go.dev/github.com/btcsuite/btcd/btcec/v2?status.png)](https://pkg.go.dev/github.com/btcsuite/btcd/btcec/v2) + +Package btcec implements elliptic curve cryptography needed for working with +Bitcoin (secp256k1 only for now). It is designed so that it may be used with the +standard crypto/ecdsa packages provided with go. A comprehensive suite of test +is provided to ensure proper functionality. Package btcec was originally based +on work from ThePiachu which is licensed under the same terms as Go, but it has +significantly diverged since then. The btcsuite developers original is licensed +under the liberal ISC license. + +Although this package was primarily written for btcd, it has intentionally been +designed so it can be used as a standalone package for any projects needing to +use secp256k1 elliptic curve cryptography. + +## Installation and Updating + +```bash +$ go install -u -v github.com/btcsuite/btcd/btcec/v2 +``` + +## Examples + +* [Sign Message](https://pkg.go.dev/github.com/btcsuite/btcd/btcec/v2#example-package--SignMessage) + Demonstrates signing a message with a secp256k1 private key that is first + parsed form raw bytes and serializing the generated signature. + +* [Verify Signature](https://pkg.go.dev/github.com/btcsuite/btcd/btcec/v2#example-package--VerifySignature) + Demonstrates verifying a secp256k1 signature against a public key that is + first parsed from raw bytes. The signature is also parsed from raw bytes. + +## License + +Package btcec is licensed under the [copyfree](http://copyfree.org) ISC License +except for btcec.go and btcec_test.go which is under the same license as Go. + diff --git a/vendor/github.com/btcsuite/btcd/btcec/v2/btcec.go b/vendor/github.com/btcsuite/btcd/btcec/v2/btcec.go new file mode 100644 index 00000000..f85baba8 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcec/v2/btcec.go @@ -0,0 +1,56 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Copyright 2011 ThePiachu. All rights reserved. +// Copyright 2013-2014 The btcsuite developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcec + +// References: +// [SECG]: Recommended Elliptic Curve Domain Parameters +// http://www.secg.org/sec2-v2.pdf +// +// [GECC]: Guide to Elliptic Curve Cryptography (Hankerson, Menezes, Vanstone) + +// This package operates, internally, on Jacobian coordinates. For a given +// (x, y) position on the curve, the Jacobian coordinates are (x1, y1, z1) +// where x = x1/z1² and y = y1/z1³. The greatest speedups come when the whole +// calculation can be performed within the transform (as in ScalarMult and +// ScalarBaseMult). But even for Add and Double, it's faster to apply and +// reverse the transform than to operate in affine coordinates. + +import ( + secp "github.com/decred/dcrd/dcrec/secp256k1/v4" +) + +// KoblitzCurve provides an implementation for secp256k1 that fits the ECC +// Curve interface from crypto/elliptic. +type KoblitzCurve = secp.KoblitzCurve + +// S256 returns a Curve which implements secp256k1. +func S256() *KoblitzCurve { + return secp.S256() +} + +// CurveParams contains the parameters for the secp256k1 curve. +type CurveParams = secp.CurveParams + +// Params returns the secp256k1 curve parameters for convenience. +func Params() *CurveParams { + return secp.Params() +} + +// Generator returns the public key at the Generator Point. +func Generator() *PublicKey { + var ( + result JacobianPoint + k secp.ModNScalar + ) + + k.SetInt(1) + ScalarBaseMultNonConst(&k, &result) + + result.ToAffine() + + return NewPublicKey(&result.X, &result.Y) +} diff --git a/vendor/github.com/btcsuite/btcd/btcec/v2/ciphering.go b/vendor/github.com/btcsuite/btcd/btcec/v2/ciphering.go new file mode 100644 index 00000000..88d93e27 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcec/v2/ciphering.go @@ -0,0 +1,16 @@ +// Copyright (c) 2015-2016 The btcsuite developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcec + +import ( + secp "github.com/decred/dcrd/dcrec/secp256k1/v4" +) + +// GenerateSharedSecret generates a shared secret based on a private key and a +// public key using Diffie-Hellman key exchange (ECDH) (RFC 4753). +// RFC5903 Section 9 states we should only return x. +func GenerateSharedSecret(privkey *PrivateKey, pubkey *PublicKey) []byte { + return secp.GenerateSharedSecret(privkey, pubkey) +} diff --git a/vendor/github.com/btcsuite/btcd/btcec/v2/curve.go b/vendor/github.com/btcsuite/btcd/btcec/v2/curve.go new file mode 100644 index 00000000..70a9229f --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcec/v2/curve.go @@ -0,0 +1,115 @@ +// Copyright (c) 2015-2021 The btcsuite developers +// Copyright (c) 2015-2021 The Decred developers + +package btcec + +import ( + "fmt" + + secp "github.com/decred/dcrd/dcrec/secp256k1/v4" +) + +// JacobianPoint is an element of the group formed by the secp256k1 curve in +// Jacobian projective coordinates and thus represents a point on the curve. +type JacobianPoint = secp.JacobianPoint + +// infinityPoint is the jacobian representation of the point at infinity. +var infinityPoint JacobianPoint + +// MakeJacobianPoint returns a Jacobian point with the provided X, Y, and Z +// coordinates. +func MakeJacobianPoint(x, y, z *FieldVal) JacobianPoint { + return secp.MakeJacobianPoint(x, y, z) +} + +// AddNonConst adds the passed Jacobian points together and stores the result +// in the provided result param in *non-constant* time. +func AddNonConst(p1, p2, result *JacobianPoint) { + secp.AddNonConst(p1, p2, result) +} + +// DecompressY attempts to calculate the Y coordinate for the given X +// coordinate such that the result pair is a point on the secp256k1 curve. It +// adjusts Y based on the desired oddness and returns whether or not it was +// successful since not all X coordinates are valid. +// +// The magnitude of the provided X coordinate field val must be a max of 8 for +// a correct result. The resulting Y field val will have a max magnitude of 2. +func DecompressY(x *FieldVal, odd bool, resultY *FieldVal) bool { + return secp.DecompressY(x, odd, resultY) +} + +// DoubleNonConst doubles the passed Jacobian point and stores the result in +// the provided result parameter in *non-constant* time. +// +// NOTE: The point must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func DoubleNonConst(p, result *JacobianPoint) { + secp.DoubleNonConst(p, result) +} + +// ScalarBaseMultNonConst multiplies k*G where G is the base point of the group +// and k is a big endian integer. The result is stored in Jacobian coordinates +// (x1, y1, z1). +// +// NOTE: The resulting point will be normalized. +func ScalarBaseMultNonConst(k *ModNScalar, result *JacobianPoint) { + secp.ScalarBaseMultNonConst(k, result) +} + +// ScalarMultNonConst multiplies k*P where k is a big endian integer modulo the +// curve order and P is a point in Jacobian projective coordinates and stores +// the result in the provided Jacobian point. +// +// NOTE: The point must be normalized for this function to return the correct +// result. The resulting point will be normalized. +func ScalarMultNonConst(k *ModNScalar, point, result *JacobianPoint) { + secp.ScalarMultNonConst(k, point, result) +} + +// ParseJacobian parses a byte slice point as a secp.Publickey and returns the +// pubkey as a JacobianPoint. If the nonce is a zero slice, the infinityPoint +// is returned. +func ParseJacobian(point []byte) (JacobianPoint, error) { + var result JacobianPoint + + if len(point) != 33 { + str := fmt.Sprintf("invalid nonce: invalid length: %v", + len(point)) + return JacobianPoint{}, makeError(secp.ErrPubKeyInvalidLen, str) + } + + if point[0] == 0x00 { + return infinityPoint, nil + } + + noncePk, err := secp.ParsePubKey(point) + if err != nil { + return JacobianPoint{}, err + } + noncePk.AsJacobian(&result) + + return result, nil +} + +// JacobianToByteSlice converts the passed JacobianPoint to a Pubkey +// and serializes that to a byte slice. If the JacobianPoint is the infinity +// point, a zero slice is returned. +func JacobianToByteSlice(point JacobianPoint) []byte { + if point.X == infinityPoint.X && point.Y == infinityPoint.Y { + return make([]byte, 33) + } + + point.ToAffine() + + return NewPublicKey( + &point.X, &point.Y, + ).SerializeCompressed() +} + +// GeneratorJacobian sets the passed JacobianPoint to the Generator Point. +func GeneratorJacobian(jacobian *JacobianPoint) { + var k ModNScalar + k.SetInt(1) + ScalarBaseMultNonConst(&k, jacobian) +} diff --git a/vendor/github.com/btcsuite/btcd/btcec/v2/doc.go b/vendor/github.com/btcsuite/btcd/btcec/v2/doc.go new file mode 100644 index 00000000..fa8346ab --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcec/v2/doc.go @@ -0,0 +1,21 @@ +// Copyright (c) 2013-2014 The btcsuite developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +/* +Package btcec implements support for the elliptic curves needed for bitcoin. + +Bitcoin uses elliptic curve cryptography using koblitz curves +(specifically secp256k1) for cryptographic functions. See +http://www.secg.org/collateral/sec2_final.pdf for details on the +standard. + +This package provides the data structures and functions implementing the +crypto/elliptic Curve interface in order to permit using these curves +with the standard crypto/ecdsa package provided with go. Helper +functionality is provided to parse signatures and public keys from +standard formats. It was designed for use with btcd, but should be +general enough for other uses of elliptic curve crypto. It was originally based +on some initial work by ThePiachu, but has significantly diverged since then. +*/ +package btcec diff --git a/vendor/github.com/btcsuite/btcd/btcec/v2/error.go b/vendor/github.com/btcsuite/btcd/btcec/v2/error.go new file mode 100644 index 00000000..df6ec678 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcec/v2/error.go @@ -0,0 +1,24 @@ +// Copyright (c) 2013-2021 The btcsuite developers +// Copyright (c) 2015-2021 The Decred developers + +package btcec + +import ( + secp "github.com/decred/dcrd/dcrec/secp256k1/v4" +) + +// Error identifies an error related to public key cryptography using a +// sec256k1 curve. It has full support for errors.Is and errors.As, so the +// caller can ascertain the specific reason for the error by checking the +// underlying error. +type Error = secp.Error + +// ErrorKind identifies a kind of error. It has full support for errors.Is and +// errors.As, so the caller can directly check against an error kind when +// determining the reason for an error. +type ErrorKind = secp.ErrorKind + +// makeError creates an secp.Error given a set of arguments. +func makeError(kind ErrorKind, desc string) Error { + return Error{Err: kind, Description: desc} +} diff --git a/vendor/github.com/btcsuite/btcd/btcec/v2/field.go b/vendor/github.com/btcsuite/btcd/btcec/v2/field.go new file mode 100644 index 00000000..fef6f345 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcec/v2/field.go @@ -0,0 +1,43 @@ +package btcec + +import secp "github.com/decred/dcrd/dcrec/secp256k1/v4" + +// FieldVal implements optimized fixed-precision arithmetic over the secp256k1 +// finite field. This means all arithmetic is performed modulo +// '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'. +// +// WARNING: Since it is so important for the field arithmetic to be extremely +// fast for high performance crypto, this type does not perform any validation +// of documented preconditions where it ordinarily would. As a result, it is +// IMPERATIVE for callers to understand some key concepts that are described +// below and ensure the methods are called with the necessary preconditions +// that each method is documented with. For example, some methods only give the +// correct result if the field value is normalized and others require the field +// values involved to have a maximum magnitude and THERE ARE NO EXPLICIT CHECKS +// TO ENSURE THOSE PRECONDITIONS ARE SATISFIED. This does, unfortunately, make +// the type more difficult to use correctly and while I typically prefer to +// ensure all state and input is valid for most code, this is a bit of an +// exception because those extra checks really add up in what ends up being +// critical hot paths. +// +// The first key concept when working with this type is normalization. In order +// to avoid the need to propagate a ton of carries, the internal representation +// provides additional overflow bits for each word of the overall 256-bit +// value. This means that there are multiple internal representations for the +// same value and, as a result, any methods that rely on comparison of the +// value, such as equality and oddness determination, require the caller to +// provide a normalized value. +// +// The second key concept when working with this type is magnitude. As +// previously mentioned, the internal representation provides additional +// overflow bits which means that the more math operations that are performed +// on the field value between normalizations, the more those overflow bits +// accumulate. The magnitude is effectively that maximum possible number of +// those overflow bits that could possibly be required as a result of a given +// operation. Since there are only a limited number of overflow bits available, +// this implies that the max possible magnitude MUST be tracked by the caller +// and the caller MUST normalize the field value if a given operation would +// cause the magnitude of the result to exceed the max allowed value. +// +// IMPORTANT: The max allowed magnitude of a field value is 64. +type FieldVal = secp.FieldVal diff --git a/vendor/github.com/btcsuite/btcd/btcec/v2/modnscalar.go b/vendor/github.com/btcsuite/btcd/btcec/v2/modnscalar.go new file mode 100644 index 00000000..939b0c17 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcec/v2/modnscalar.go @@ -0,0 +1,45 @@ +// Copyright (c) 2013-2021 The btcsuite developers +// Copyright (c) 2015-2021 The Decred developers + +package btcec + +import ( + secp "github.com/decred/dcrd/dcrec/secp256k1/v4" +) + +// ModNScalar implements optimized 256-bit constant-time fixed-precision +// arithmetic over the secp256k1 group order. This means all arithmetic is +// performed modulo: +// +// 0xfffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141 +// +// It only implements the arithmetic needed for elliptic curve operations, +// however, the operations that are not implemented can typically be worked +// around if absolutely needed. For example, subtraction can be performed by +// adding the negation. +// +// Should it be absolutely necessary, conversion to the standard library +// math/big.Int can be accomplished by using the Bytes method, slicing the +// resulting fixed-size array, and feeding it to big.Int.SetBytes. However, +// that should typically be avoided when possible as conversion to big.Ints +// requires allocations, is not constant time, and is slower when working modulo +// the group order. +type ModNScalar = secp.ModNScalar + +// NonceRFC6979 generates a nonce deterministically according to RFC 6979 using +// HMAC-SHA256 for the hashing function. It takes a 32-byte hash as an input +// and returns a 32-byte nonce to be used for deterministic signing. The extra +// and version arguments are optional, but allow additional data to be added to +// the input of the HMAC. When provided, the extra data must be 32-bytes and +// version must be 16 bytes or they will be ignored. +// +// Finally, the extraIterations parameter provides a method to produce a stream +// of deterministic nonces to ensure the signing code is able to produce a nonce +// that results in a valid signature in the extremely unlikely event the +// original nonce produced results in an invalid signature (e.g. R == 0). +// Signing code should start with 0 and increment it if necessary. +func NonceRFC6979(privKey []byte, hash []byte, extra []byte, version []byte, + extraIterations uint32) *ModNScalar { + + return secp.NonceRFC6979(privKey, hash, extra, version, extraIterations) +} diff --git a/vendor/github.com/btcsuite/btcd/btcec/v2/privkey.go b/vendor/github.com/btcsuite/btcd/btcec/v2/privkey.go new file mode 100644 index 00000000..d0dbd8d9 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcec/v2/privkey.go @@ -0,0 +1,37 @@ +// Copyright (c) 2013-2016 The btcsuite developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcec + +import ( + secp "github.com/decred/dcrd/dcrec/secp256k1/v4" +) + +// PrivateKey wraps an ecdsa.PrivateKey as a convenience mainly for signing +// things with the private key without having to directly import the ecdsa +// package. +type PrivateKey = secp.PrivateKey + +// PrivKeyFromBytes returns a private and public key for `curve' based on the +// private key passed as an argument as a byte slice. +func PrivKeyFromBytes(pk []byte) (*PrivateKey, *PublicKey) { + privKey := secp.PrivKeyFromBytes(pk) + + return privKey, privKey.PubKey() +} + +// NewPrivateKey is a wrapper for ecdsa.GenerateKey that returns a PrivateKey +// instead of the normal ecdsa.PrivateKey. +func NewPrivateKey() (*PrivateKey, error) { + return secp.GeneratePrivateKey() +} + +// PrivKeyFromScalar instantiates a new private key from a scalar encoded as a +// big integer. +func PrivKeyFromScalar(key *ModNScalar) *PrivateKey { + return &PrivateKey{Key: *key} +} + +// PrivKeyBytesLen defines the length in bytes of a serialized private key. +const PrivKeyBytesLen = 32 diff --git a/vendor/github.com/btcsuite/btcd/btcec/v2/pubkey.go b/vendor/github.com/btcsuite/btcd/btcec/v2/pubkey.go new file mode 100644 index 00000000..2c3a5ccb --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcec/v2/pubkey.go @@ -0,0 +1,88 @@ +// Copyright (c) 2013-2014 The btcsuite developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package btcec + +import ( + secp "github.com/decred/dcrd/dcrec/secp256k1/v4" +) + +// These constants define the lengths of serialized public keys. +const ( + // PubKeyBytesLenCompressed is the bytes length of a serialized compressed + // public key. + PubKeyBytesLenCompressed = 33 +) + +const ( + pubkeyCompressed byte = 0x2 // y_bit + x coord + pubkeyUncompressed byte = 0x4 // x coord + y coord + pubkeyHybrid byte = 0x6 // y_bit + x coord + y coord +) + +// IsCompressedPubKey returns true the passed serialized public key has +// been encoded in compressed format, and false otherwise. +func IsCompressedPubKey(pubKey []byte) bool { + // The public key is only compressed if it is the correct length and + // the format (first byte) is one of the compressed pubkey values. + return len(pubKey) == PubKeyBytesLenCompressed && + (pubKey[0]&^byte(0x1) == pubkeyCompressed) +} + +// ParsePubKey parses a public key for a koblitz curve from a bytestring into a +// ecdsa.Publickey, verifying that it is valid. It supports compressed, +// uncompressed and hybrid signature formats. +func ParsePubKey(pubKeyStr []byte) (*PublicKey, error) { + return secp.ParsePubKey(pubKeyStr) +} + +// PublicKey is an ecdsa.PublicKey with additional functions to +// serialize in uncompressed, compressed, and hybrid formats. +type PublicKey = secp.PublicKey + +// NewPublicKey instantiates a new public key with the given x and y +// coordinates. +// +// It should be noted that, unlike ParsePubKey, since this accepts arbitrary x +// and y coordinates, it allows creation of public keys that are not valid +// points on the secp256k1 curve. The IsOnCurve method of the returned instance +// can be used to determine validity. +func NewPublicKey(x, y *FieldVal) *PublicKey { + return secp.NewPublicKey(x, y) +} + +// SerializedKey is a type for representing a public key in its compressed +// serialized form. +// +// NOTE: This type is useful when using public keys as keys in maps. +type SerializedKey [PubKeyBytesLenCompressed]byte + +// ToPubKey returns the public key parsed from the serialized key. +func (s SerializedKey) ToPubKey() (*PublicKey, error) { + return ParsePubKey(s[:]) +} + +// SchnorrSerialized returns the Schnorr serialized, x-only 32-byte +// representation of the serialized key. +func (s SerializedKey) SchnorrSerialized() [32]byte { + var serializedSchnorr [32]byte + copy(serializedSchnorr[:], s[1:]) + return serializedSchnorr +} + +// CopyBytes returns a copy of the underlying array as a byte slice. +func (s SerializedKey) CopyBytes() []byte { + c := make([]byte, PubKeyBytesLenCompressed) + copy(c, s[:]) + + return c +} + +// ToSerialized serializes a public key into its compressed form. +func ToSerialized(pubKey *PublicKey) SerializedKey { + var serialized SerializedKey + copy(serialized[:], pubKey.SerializeCompressed()) + + return serialized +} diff --git a/vendor/github.com/btcsuite/btcd/btcec/v2/schnorr/error.go b/vendor/github.com/btcsuite/btcd/btcec/v2/schnorr/error.go new file mode 100644 index 00000000..40143396 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcec/v2/schnorr/error.go @@ -0,0 +1,25 @@ +// Copyright (c) 2013-2017 The btcsuite developers +// Copyright (c) 2015-2021 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package schnorr + +import ( + ecdsa_schnorr "github.com/decred/dcrd/dcrec/secp256k1/v4/schnorr" +) + +// ErrorKind identifies a kind of error. It has full support for errors.Is +// and errors.As, so the caller can directly check against an error kind +// when determining the reason for an error. +type ErrorKind = ecdsa_schnorr.ErrorKind + +// Error identifies an error related to a schnorr signature. It has full +// support for errors.Is and errors.As, so the caller can ascertain the +// specific reason for the error by checking the underlying error. +type Error = ecdsa_schnorr.Error + +// signatureError creates an Error given a set of arguments. +func signatureError(kind ErrorKind, desc string) Error { + return Error{Err: kind, Description: desc} +} diff --git a/vendor/github.com/btcsuite/btcd/btcec/v2/schnorr/pubkey.go b/vendor/github.com/btcsuite/btcd/btcec/v2/schnorr/pubkey.go new file mode 100644 index 00000000..f5d2ca4b --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcec/v2/schnorr/pubkey.go @@ -0,0 +1,49 @@ +// Copyright (c) 2013-2017 The btcsuite developers +// Copyright (c) 2015-2021 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package schnorr + +import ( + "fmt" + + "github.com/btcsuite/btcd/btcec/v2" + secp "github.com/decred/dcrd/dcrec/secp256k1/v4" +) + +// These constants define the lengths of serialized public keys. +const ( + PubKeyBytesLen = 32 +) + +// ParsePubKey parses a public key for a koblitz curve from a bytestring into a +// btcec.Publickey, verifying that it is valid. It only supports public keys in +// the BIP-340 32-byte format. +func ParsePubKey(pubKeyStr []byte) (*btcec.PublicKey, error) { + if pubKeyStr == nil { + err := fmt.Errorf("nil pubkey byte string") + return nil, err + } + if len(pubKeyStr) != PubKeyBytesLen { + err := fmt.Errorf("bad pubkey byte string size (want %v, have %v)", + PubKeyBytesLen, len(pubKeyStr)) + return nil, err + } + + // We'll manually prepend the compressed byte so we can re-use the + // existing pubkey parsing routine of the main btcec package. + var keyCompressed [btcec.PubKeyBytesLenCompressed]byte + keyCompressed[0] = secp.PubKeyFormatCompressedEven + copy(keyCompressed[1:], pubKeyStr) + + return btcec.ParsePubKey(keyCompressed[:]) +} + +// SerializePubKey serializes a public key as specified by BIP 340. Public keys +// in this format are 32 bytes in length, and are assumed to have an even y +// coordinate. +func SerializePubKey(pub *btcec.PublicKey) []byte { + pBytes := pub.SerializeCompressed() + return pBytes[1:] +} diff --git a/vendor/github.com/btcsuite/btcd/btcec/v2/schnorr/signature.go b/vendor/github.com/btcsuite/btcd/btcec/v2/schnorr/signature.go new file mode 100644 index 00000000..8876a607 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcec/v2/schnorr/signature.go @@ -0,0 +1,538 @@ +// Copyright (c) 2013-2022 The btcsuite developers + +package schnorr + +import ( + "fmt" + + "github.com/btcsuite/btcd/btcec/v2" + "github.com/btcsuite/btcd/chaincfg/chainhash" + secp "github.com/decred/dcrd/dcrec/secp256k1/v4" + ecdsa_schnorr "github.com/decred/dcrd/dcrec/secp256k1/v4/schnorr" +) + +const ( + // SignatureSize is the size of an encoded Schnorr signature. + SignatureSize = 64 + + // scalarSize is the size of an encoded big endian scalar. + scalarSize = 32 +) + +var ( + // rfc6979ExtraDataV0 is the extra data to feed to RFC6979 when + // generating the deterministic nonce for the BIP-340 scheme. This + // ensures the same nonce is not generated for the same message and key + // as for other signing algorithms such as ECDSA. + // + // It is equal to SHA-256([]byte("BIP-340")). + rfc6979ExtraDataV0 = [32]uint8{ + 0xa3, 0xeb, 0x4c, 0x18, 0x2f, 0xae, 0x7e, 0xf4, + 0xe8, 0x10, 0xc6, 0xee, 0x13, 0xb0, 0xe9, 0x26, + 0x68, 0x6d, 0x71, 0xe8, 0x7f, 0x39, 0x4f, 0x79, + 0x9c, 0x00, 0xa5, 0x21, 0x03, 0xcb, 0x4e, 0x17, + } +) + +// Signature is a type representing a Schnorr signature. +type Signature struct { + r btcec.FieldVal + s btcec.ModNScalar +} + +// NewSignature instantiates a new signature given some r and s values. +func NewSignature(r *btcec.FieldVal, s *btcec.ModNScalar) *Signature { + var sig Signature + sig.r.Set(r).Normalize() + sig.s.Set(s) + return &sig +} + +// Serialize returns the Schnorr signature in the more strict format. +// +// The signatures are encoded as +// +// sig[0:32] x coordinate of the point R, encoded as a big-endian uint256 +// sig[32:64] s, encoded also as big-endian uint256 +func (sig Signature) Serialize() []byte { + // Total length of returned signature is the length of r and s. + var b [SignatureSize]byte + sig.r.PutBytesUnchecked(b[0:32]) + sig.s.PutBytesUnchecked(b[32:64]) + return b[:] +} + +// ParseSignature parses a signature according to the BIP-340 specification and +// enforces the following additional restrictions specific to secp256k1: +// +// - The r component must be in the valid range for secp256k1 field elements +// - The s component must be in the valid range for secp256k1 scalars +func ParseSignature(sig []byte) (*Signature, error) { + // The signature must be the correct length. + sigLen := len(sig) + if sigLen < SignatureSize { + str := fmt.Sprintf("malformed signature: too short: %d < %d", sigLen, + SignatureSize) + return nil, signatureError(ecdsa_schnorr.ErrSigTooShort, str) + } + if sigLen > SignatureSize { + str := fmt.Sprintf("malformed signature: too long: %d > %d", sigLen, + SignatureSize) + return nil, signatureError(ecdsa_schnorr.ErrSigTooLong, str) + } + + // The signature is validly encoded at this point, however, enforce + // additional restrictions to ensure r is in the range [0, p-1], and s is in + // the range [0, n-1] since valid Schnorr signatures are required to be in + // that range per spec. + var r btcec.FieldVal + if overflow := r.SetByteSlice(sig[0:32]); overflow { + str := "invalid signature: r >= field prime" + return nil, signatureError(ecdsa_schnorr.ErrSigRTooBig, str) + } + var s btcec.ModNScalar + s.SetByteSlice(sig[32:64]) + + // Return the signature. + return NewSignature(&r, &s), nil +} + +// IsEqual compares this Signature instance to the one passed, returning true +// if both Signatures are equivalent. A signature is equivalent to another, if +// they both have the same scalar value for R and S. +func (sig Signature) IsEqual(otherSig *Signature) bool { + return sig.r.Equals(&otherSig.r) && sig.s.Equals(&otherSig.s) +} + +// schnorrVerify attempt to verify the signature for the provided hash and +// secp256k1 public key and either returns nil if successful or a specific error +// indicating why it failed if not successful. +// +// This differs from the exported Verify method in that it returns a specific +// error to support better testing while the exported method simply returns a +// bool indicating success or failure. +func schnorrVerify(sig *Signature, hash []byte, pubKeyBytes []byte) error { + // The algorithm for producing a BIP-340 signature is described in + // README.md and is reproduced here for reference: + // + // 1. Fail if m is not 32 bytes + // 2. P = lift_x(int(pk)). + // 3. r = int(sig[0:32]); fail is r >= p. + // 4. s = int(sig[32:64]); fail if s >= n. + // 5. e = int(tagged_hash("BIP0340/challenge", bytes(r) || bytes(P) || M)) mod n. + // 6. R = s*G - e*P + // 7. Fail if is_infinite(R) + // 8. Fail if not hash_even_y(R) + // 9. Fail is x(R) != r. + // 10. Return success iff failure did not occur before reaching this point. + + // Step 1. + // + // Fail if m is not 32 bytes + if len(hash) != scalarSize { + str := fmt.Sprintf("wrong size for message (got %v, want %v)", + len(hash), scalarSize) + return signatureError(ecdsa_schnorr.ErrInvalidHashLen, str) + } + + // Step 2. + // + // P = lift_x(int(pk)) + // + // Fail if P is not a point on the curve + pubKey, err := ParsePubKey(pubKeyBytes) + if err != nil { + return err + } + if !pubKey.IsOnCurve() { + str := "pubkey point is not on curve" + return signatureError(ecdsa_schnorr.ErrPubKeyNotOnCurve, str) + } + + // Step 3. + // + // Fail if r >= p + // + // Note this is already handled by the fact r is a field element. + + // Step 4. + // + // Fail if s >= n + // + // Note this is already handled by the fact s is a mod n scalar. + + // Step 5. + // + // e = int(tagged_hash("BIP0340/challenge", bytes(r) || bytes(P) || M)) mod n. + var rBytes [32]byte + sig.r.PutBytesUnchecked(rBytes[:]) + pBytes := SerializePubKey(pubKey) + + commitment := chainhash.TaggedHash( + chainhash.TagBIP0340Challenge, rBytes[:], pBytes, hash, + ) + + var e btcec.ModNScalar + e.SetBytes((*[32]byte)(commitment)) + + // Negate e here so we can use AddNonConst below to subtract the s*G + // point from e*P. + e.Negate() + + // Step 6. + // + // R = s*G - e*P + var P, R, sG, eP btcec.JacobianPoint + pubKey.AsJacobian(&P) + btcec.ScalarBaseMultNonConst(&sig.s, &sG) + btcec.ScalarMultNonConst(&e, &P, &eP) + btcec.AddNonConst(&sG, &eP, &R) + + // Step 7. + // + // Fail if R is the point at infinity + if (R.X.IsZero() && R.Y.IsZero()) || R.Z.IsZero() { + str := "calculated R point is the point at infinity" + return signatureError(ecdsa_schnorr.ErrSigRNotOnCurve, str) + } + + // Step 8. + // + // Fail if R.y is odd + // + // Note that R must be in affine coordinates for this check. + R.ToAffine() + if R.Y.IsOdd() { + str := "calculated R y-value is odd" + return signatureError(ecdsa_schnorr.ErrSigRYIsOdd, str) + } + + // Step 9. + // + // Verified if R.x == r + // + // Note that R must be in affine coordinates for this check. + if !sig.r.Equals(&R.X) { + str := "calculated R point was not given R" + return signatureError(ecdsa_schnorr.ErrUnequalRValues, str) + } + + // Step 10. + // + // Return success iff failure did not occur before reaching this point. + return nil +} + +// Verify returns whether or not the signature is valid for the provided hash +// and secp256k1 public key. +func (sig *Signature) Verify(hash []byte, pubKey *btcec.PublicKey) bool { + pubkeyBytes := SerializePubKey(pubKey) + return schnorrVerify(sig, hash, pubkeyBytes) == nil +} + +// zeroArray zeroes the memory of a scalar array. +func zeroArray(a *[scalarSize]byte) { + for i := 0; i < scalarSize; i++ { + a[i] = 0x00 + } +} + +// schnorrSign generates a BIP-340 signature over the secp256k1 curve for the +// provided hash (which should be the result of hashing a larger message) using +// the given nonce and private key. The produced signature is deterministic +// (same message, nonce, and key yield the same signature) and canonical. +// +// WARNING: The hash MUST be 32 bytes and both the nonce and private keys must +// NOT be 0. Since this is an internal use function, these preconditions MUST +// be satisfied by the caller. +func schnorrSign(privKey, nonce *btcec.ModNScalar, pubKey *btcec.PublicKey, hash []byte, + opts *signOptions) (*Signature, error) { + + // The algorithm for producing a BIP-340 signature is described in + // README.md and is reproduced here for reference: + // + // G = curve generator + // n = curve order + // d = private key + // m = message + // a = input randomness + // r, s = signature + // + // 1. d' = int(d) + // 2. Fail if m is not 32 bytes + // 3. Fail if d = 0 or d >= n + // 4. P = d'*G + // 5. Negate d if P.y is odd + // 6. t = bytes(d) xor tagged_hash("BIP0340/aux", t || bytes(P) || m) + // 7. rand = tagged_hash("BIP0340/nonce", a) + // 8. k' = int(rand) mod n + // 9. Fail if k' = 0 + // 10. R = 'k*G + // 11. Negate k if R.y id odd + // 12. e = tagged_hash("BIP0340/challenge", bytes(R) || bytes(P) || m) mod n + // 13. sig = bytes(R) || bytes((k + e*d)) mod n + // 14. If Verify(bytes(P), m, sig) fails, abort. + // 15. return sig. + // + // Note that the set of functional options passed in may modify the + // above algorithm. Namely if CustomNonce is used, then steps 6-8 are + // replaced with a process that generates the nonce using rfc6979. If + // FastSign is passed, then we skip set 14. + + // NOTE: Steps 1-9 are performed by the caller. + + // + // Step 10. + // + // R = kG + var R btcec.JacobianPoint + k := *nonce + btcec.ScalarBaseMultNonConst(&k, &R) + + // Step 11. + // + // Negate nonce k if R.y is odd (R.y is the y coordinate of the point R) + // + // Note that R must be in affine coordinates for this check. + R.ToAffine() + if R.Y.IsOdd() { + k.Negate() + } + + // Step 12. + // + // e = tagged_hash("BIP0340/challenge", bytes(R) || bytes(P) || m) mod n + pBytes := SerializePubKey(pubKey) + commitment := chainhash.TaggedHash( + chainhash.TagBIP0340Challenge, R.X.Bytes()[:], pBytes, hash, + ) + + var e btcec.ModNScalar + if overflow := e.SetBytes((*[32]byte)(commitment)); overflow != 0 { + k.Zero() + str := "hash of (r || P || m) too big" + return nil, signatureError(ecdsa_schnorr.ErrSchnorrHashValue, str) + } + + // Step 13. + // + // s = k + e*d mod n + s := new(btcec.ModNScalar).Mul2(&e, privKey).Add(&k) + k.Zero() + + sig := NewSignature(&R.X, s) + + // Step 14. + // + // If Verify(bytes(P), m, sig) fails, abort. + if !opts.fastSign { + if err := schnorrVerify(sig, hash, pBytes); err != nil { + return nil, err + } + } + + // Step 15. + // + // Return (r, s) + return sig, nil +} + +// SignOption is a functional option argument that allows callers to modify the +// way we generate BIP-340 schnorr signatures. +type SignOption func(*signOptions) + +// signOptions houses the set of functional options that can be used to modify +// the method used to generate the BIP-340 signature. +type signOptions struct { + // fastSign determines if we'll skip the check at the end of the routine + // where we attempt to verify the produced signature. + fastSign bool + + // authNonce allows the user to pass in their own nonce information, which + // is useful for schemes like mu-sig. + authNonce *[32]byte +} + +// defaultSignOptions returns the default set of signing operations. +func defaultSignOptions() *signOptions { + return &signOptions{} +} + +// FastSign forces signing to skip the extra verification step at the end. +// Performance sensitive applications may opt to use this option to speed up the +// signing operation. +func FastSign() SignOption { + return func(o *signOptions) { + o.fastSign = true + } +} + +// CustomNonce allows users to pass in a custom set of auxData that's used as +// input randomness to generate the nonce used during signing. Users may want +// to specify this custom value when using multi-signatures schemes such as +// Mu-Sig2. If this option isn't set, then rfc6979 will be used to generate the +// nonce material. +func CustomNonce(auxData [32]byte) SignOption { + return func(o *signOptions) { + o.authNonce = &auxData + } +} + +// Sign generates an BIP-340 signature over the secp256k1 curve for the +// provided hash (which should be the result of hashing a larger message) using +// the given private key. The produced signature is deterministic (same +// message and same key yield the same signature) and canonical. +// +// Note that the current signing implementation has a few remaining variable +// time aspects which make use of the private key and the generated nonce, +// which can expose the signer to constant time attacks. As a result, this +// function should not be used in situations where there is the possibility of +// someone having EM field/cache/etc access. +func Sign(privKey *btcec.PrivateKey, hash []byte, + signOpts ...SignOption) (*Signature, error) { + + // First, parse the set of optional signing options. + opts := defaultSignOptions() + for _, option := range signOpts { + option(opts) + } + + // The algorithm for producing a BIP-340 signature is described in + // README.md and is reproduced here for reference: + // + // G = curve generator + // n = curve order + // d = private key + // m = message + // a = input randomness + // r, s = signature + // + // 1. d' = int(d) + // 2. Fail if m is not 32 bytes + // 3. Fail if d = 0 or d >= n + // 4. P = d'*G + // 5. Negate d if P.y is odd + // 6. t = bytes(d) xor tagged_hash("BIP0340/aux", t || bytes(P) || m) + // 7. rand = tagged_hash("BIP0340/nonce", a) + // 8. k' = int(rand) mod n + // 9. Fail if k' = 0 + // 10. R = 'k*G + // 11. Negate k if R.y id odd + // 12. e = tagged_hash("BIP0340/challenge", bytes(R) || bytes(P) || mod) mod n + // 13. sig = bytes(R) || bytes((k + e*d)) mod n + // 14. If Verify(bytes(P), m, sig) fails, abort. + // 15. return sig. + // + // Note that the set of functional options passed in may modify the + // above algorithm. Namely if CustomNonce is used, then steps 6-8 are + // replaced with a process that generates the nonce using rfc6979. If + // FastSign is passed, then we skip set 14. + + // Step 1. + // + // d' = int(d) + var privKeyScalar btcec.ModNScalar + privKeyScalar.Set(&privKey.Key) + + // Step 2. + // + // Fail if m is not 32 bytes + if len(hash) != scalarSize { + str := fmt.Sprintf("wrong size for message hash (got %v, want %v)", + len(hash), scalarSize) + return nil, signatureError(ecdsa_schnorr.ErrInvalidHashLen, str) + } + + // Step 3. + // + // Fail if d = 0 or d >= n + if privKeyScalar.IsZero() { + str := "private key is zero" + return nil, signatureError(ecdsa_schnorr.ErrPrivateKeyIsZero, str) + } + + // Step 4. + // + // P = 'd*G + pub := privKey.PubKey() + + // Step 5. + // + // Negate d if P.y is odd. + pubKeyBytes := pub.SerializeCompressed() + if pubKeyBytes[0] == secp.PubKeyFormatCompressedOdd { + privKeyScalar.Negate() + } + + // At this point, we check to see if a CustomNonce has been passed in, + // and if so, then we'll deviate from the main routine here by + // generating the nonce value as specified by BIP-0340. + if opts.authNonce != nil { + // Step 6. + // + // t = bytes(d) xor tagged_hash("BIP0340/aux", a) + privBytes := privKeyScalar.Bytes() + t := chainhash.TaggedHash( + chainhash.TagBIP0340Aux, (*opts.authNonce)[:], + ) + for i := 0; i < len(t); i++ { + t[i] ^= privBytes[i] + } + + // Step 7. + // + // rand = tagged_hash("BIP0340/nonce", t || bytes(P) || m) + // + // We snip off the first byte of the serialized pubkey, as we + // only need the x coordinate and not the market byte. + rand := chainhash.TaggedHash( + chainhash.TagBIP0340Nonce, t[:], pubKeyBytes[1:], hash, + ) + + // Step 8. + // + // k'= int(rand) mod n + var kPrime btcec.ModNScalar + kPrime.SetBytes((*[32]byte)(rand)) + + // Step 9. + // + // Fail if k' = 0 + if kPrime.IsZero() { + str := fmt.Sprintf("generated nonce is zero") + return nil, signatureError(ecdsa_schnorr.ErrSchnorrHashValue, str) + } + + sig, err := schnorrSign(&privKeyScalar, &kPrime, pub, hash, opts) + kPrime.Zero() + if err != nil { + return nil, err + } + + return sig, nil + } + + var privKeyBytes [scalarSize]byte + privKeyScalar.PutBytes(&privKeyBytes) + defer zeroArray(&privKeyBytes) + for iteration := uint32(0); ; iteration++ { + // Step 6-9. + // + // Use RFC6979 to generate a deterministic nonce k in [1, n-1] + // parameterized by the private key, message being signed, extra data + // that identifies the scheme, and an iteration count + k := btcec.NonceRFC6979( + privKeyBytes[:], hash, rfc6979ExtraDataV0[:], nil, iteration, + ) + + // Steps 10-15. + sig, err := schnorrSign(&privKeyScalar, k, pub, hash, opts) + k.Zero() + if err != nil { + // Try again with a new nonce. + continue + } + + return sig, nil + } +} diff --git a/vendor/github.com/btcsuite/btcd/btcutil/LICENSE b/vendor/github.com/btcsuite/btcd/btcutil/LICENSE new file mode 100644 index 00000000..3e7b1679 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcutil/LICENSE @@ -0,0 +1,16 @@ +ISC License + +Copyright (c) 2013-2017 The btcsuite developers +Copyright (c) 2016-2017 The Lightning Network Developers + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/btcsuite/btcd/btcutil/bech32/README.md b/vendor/github.com/btcsuite/btcd/btcutil/bech32/README.md new file mode 100644 index 00000000..471cd50e --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcutil/bech32/README.md @@ -0,0 +1,29 @@ +bech32 +========== + +[![Build Status](http://img.shields.io/travis/btcsuite/btcutil.svg)](https://travis-ci.org/btcsuite/btcutil) +[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) +[![GoDoc](https://godoc.org/github.com/btcsuite/btcd/btcutil/bech32?status.png)](http://godoc.org/github.com/btcsuite/btcd/btcutil/bech32) + +Package bech32 provides a Go implementation of the bech32 format specified in +[BIP 173](https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki). + +Test vectors from BIP 173 are added to ensure compatibility with the BIP. + +## Installation and Updating + +```bash +$ go get -u github.com/btcsuite/btcd/btcutil/bech32 +``` + +## Examples + +* [Bech32 decode Example](http://godoc.org/github.com/btcsuite/btcd/btcutil/bech32#example-Bech32Decode) + Demonstrates how to decode a bech32 encoded string. +* [Bech32 encode Example](http://godoc.org/github.com/btcsuite/btcd/btcutil/bech32#example-BechEncode) + Demonstrates how to encode data into a bech32 string. + +## License + +Package bech32 is licensed under the [copyfree](http://copyfree.org) ISC +License. diff --git a/vendor/github.com/btcsuite/btcd/btcutil/bech32/bech32.go b/vendor/github.com/btcsuite/btcd/btcutil/bech32/bech32.go new file mode 100644 index 00000000..c1e00106 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcutil/bech32/bech32.go @@ -0,0 +1,442 @@ +// Copyright (c) 2017 The btcsuite developers +// Copyright (c) 2019 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package bech32 + +import ( + "strings" +) + +// charset is the set of characters used in the data section of bech32 strings. +// Note that this is ordered, such that for a given charset[i], i is the binary +// value of the character. +const charset = "qpzry9x8gf2tvdw0s3jn54khce6mua7l" + +// gen encodes the generator polynomial for the bech32 BCH checksum. +var gen = []int{0x3b6a57b2, 0x26508e6d, 0x1ea119fa, 0x3d4233dd, 0x2a1462b3} + +// toBytes converts each character in the string 'chars' to the value of the +// index of the correspoding character in 'charset'. +func toBytes(chars string) ([]byte, error) { + decoded := make([]byte, 0, len(chars)) + for i := 0; i < len(chars); i++ { + index := strings.IndexByte(charset, chars[i]) + if index < 0 { + return nil, ErrNonCharsetChar(chars[i]) + } + decoded = append(decoded, byte(index)) + } + return decoded, nil +} + +// bech32Polymod calculates the BCH checksum for a given hrp, values and +// checksum data. Checksum is optional, and if nil a 0 checksum is assumed. +// +// Values and checksum (if provided) MUST be encoded as 5 bits per element (base +// 32), otherwise the results are undefined. +// +// For more details on the polymod calculation, please refer to BIP 173. +func bech32Polymod(hrp string, values, checksum []byte) int { + chk := 1 + + // Account for the high bits of the HRP in the checksum. + for i := 0; i < len(hrp); i++ { + b := chk >> 25 + hiBits := int(hrp[i]) >> 5 + chk = (chk&0x1ffffff)<<5 ^ hiBits + for i := 0; i < 5; i++ { + if (b>>uint(i))&1 == 1 { + chk ^= gen[i] + } + } + } + + // Account for the separator (0) between high and low bits of the HRP. + // x^0 == x, so we eliminate the redundant xor used in the other rounds. + b := chk >> 25 + chk = (chk & 0x1ffffff) << 5 + for i := 0; i < 5; i++ { + if (b>>uint(i))&1 == 1 { + chk ^= gen[i] + } + } + + // Account for the low bits of the HRP. + for i := 0; i < len(hrp); i++ { + b := chk >> 25 + loBits := int(hrp[i]) & 31 + chk = (chk&0x1ffffff)<<5 ^ loBits + for i := 0; i < 5; i++ { + if (b>>uint(i))&1 == 1 { + chk ^= gen[i] + } + } + } + + // Account for the values. + for _, v := range values { + b := chk >> 25 + chk = (chk&0x1ffffff)<<5 ^ int(v) + for i := 0; i < 5; i++ { + if (b>>uint(i))&1 == 1 { + chk ^= gen[i] + } + } + } + + if checksum == nil { + // A nil checksum is used during encoding, so assume all bytes are zero. + // x^0 == x, so we eliminate the redundant xor used in the other rounds. + for v := 0; v < 6; v++ { + b := chk >> 25 + chk = (chk & 0x1ffffff) << 5 + for i := 0; i < 5; i++ { + if (b>>uint(i))&1 == 1 { + chk ^= gen[i] + } + } + } + } else { + // Checksum is provided during decoding, so use it. + for _, v := range checksum { + b := chk >> 25 + chk = (chk&0x1ffffff)<<5 ^ int(v) + for i := 0; i < 5; i++ { + if (b>>uint(i))&1 == 1 { + chk ^= gen[i] + } + } + } + } + + return chk +} + +// writeBech32Checksum calculates the checksum data expected for a string that +// will have the given hrp and payload data and writes it to the provided string +// builder. +// +// The payload data MUST be encoded as a base 32 (5 bits per element) byte slice +// and the hrp MUST only use the allowed character set (ascii chars between 33 +// and 126), otherwise the results are undefined. +// +// For more details on the checksum calculation, please refer to BIP 173. +func writeBech32Checksum(hrp string, data []byte, bldr *strings.Builder, + version Version) { + + bech32Const := int(VersionToConsts[version]) + polymod := bech32Polymod(hrp, data, nil) ^ bech32Const + for i := 0; i < 6; i++ { + b := byte((polymod >> uint(5*(5-i))) & 31) + + // This can't fail, given we explicitly cap the previous b byte by the + // first 31 bits. + c := charset[b] + bldr.WriteByte(c) + } +} + +// bech32VerifyChecksum verifies whether the bech32 string specified by the +// provided hrp and payload data (encoded as 5 bits per element byte slice) has +// the correct checksum suffix. The version of bech32 used (bech32 OG, or +// bech32m) is also returned to allow the caller to perform proper address +// validation (segwitv0 should use bech32, v1+ should use bech32m). +// +// Data MUST have more than 6 elements, otherwise this function panics. +// +// For more details on the checksum verification, please refer to BIP 173. +func bech32VerifyChecksum(hrp string, data []byte) (Version, bool) { + checksum := data[len(data)-6:] + values := data[:len(data)-6] + polymod := bech32Polymod(hrp, values, checksum) + + // Before BIP-350, we'd always check this against a static constant of + // 1 to know if the checksum was computed properly. As we want to + // generically support decoding for bech32m as well as bech32, we'll + // look up the returned value and compare it to the set of defined + // constants. + bech32Version, ok := ConstsToVersion[ChecksumConst(polymod)] + if ok { + return bech32Version, true + } + + return VersionUnknown, false +} + +// DecodeNoLimit is a bech32 checksum version aware arbitrary string length +// decoder. This function will return the version of the decoded checksum +// constant so higher level validation can be performed to ensure the correct +// version of bech32 was used when encoding. +func decodeNoLimit(bech string) (string, []byte, Version, error) { + // The minimum allowed size of a bech32 string is 8 characters, since it + // needs a non-empty HRP, a separator, and a 6 character checksum. + if len(bech) < 8 { + return "", nil, VersionUnknown, ErrInvalidLength(len(bech)) + } + + // Only ASCII characters between 33 and 126 are allowed. + var hasLower, hasUpper bool + for i := 0; i < len(bech); i++ { + if bech[i] < 33 || bech[i] > 126 { + return "", nil, VersionUnknown, ErrInvalidCharacter(bech[i]) + } + + // The characters must be either all lowercase or all uppercase. Testing + // directly with ascii codes is safe here, given the previous test. + hasLower = hasLower || (bech[i] >= 97 && bech[i] <= 122) + hasUpper = hasUpper || (bech[i] >= 65 && bech[i] <= 90) + if hasLower && hasUpper { + return "", nil, VersionUnknown, ErrMixedCase{} + } + } + + // Bech32 standard uses only the lowercase for of strings for checksum + // calculation. + if hasUpper { + bech = strings.ToLower(bech) + } + + // The string is invalid if the last '1' is non-existent, it is the + // first character of the string (no human-readable part) or one of the + // last 6 characters of the string (since checksum cannot contain '1'). + one := strings.LastIndexByte(bech, '1') + if one < 1 || one+7 > len(bech) { + return "", nil, VersionUnknown, ErrInvalidSeparatorIndex(one) + } + + // The human-readable part is everything before the last '1'. + hrp := bech[:one] + data := bech[one+1:] + + // Each character corresponds to the byte with value of the index in + // 'charset'. + decoded, err := toBytes(data) + if err != nil { + return "", nil, VersionUnknown, err + } + + // Verify if the checksum (stored inside decoded[:]) is valid, given the + // previously decoded hrp. + bech32Version, ok := bech32VerifyChecksum(hrp, decoded) + if !ok { + // Invalid checksum. Calculate what it should have been, so that the + // error contains this information. + + // Extract the payload bytes and actual checksum in the string. + actual := bech[len(bech)-6:] + payload := decoded[:len(decoded)-6] + + // Calculate the expected checksum, given the hrp and payload + // data. We'll actually compute _both_ possibly valid checksum + // to further aide in debugging. + var expectedBldr strings.Builder + expectedBldr.Grow(6) + writeBech32Checksum(hrp, payload, &expectedBldr, Version0) + expectedVersion0 := expectedBldr.String() + + var b strings.Builder + b.Grow(6) + writeBech32Checksum(hrp, payload, &expectedBldr, VersionM) + expectedVersionM := expectedBldr.String() + + err = ErrInvalidChecksum{ + Expected: expectedVersion0, + ExpectedM: expectedVersionM, + Actual: actual, + } + return "", nil, VersionUnknown, err + } + + // We exclude the last 6 bytes, which is the checksum. + return hrp, decoded[:len(decoded)-6], bech32Version, nil +} + +// DecodeNoLimit decodes a bech32 encoded string, returning the human-readable +// part and the data part excluding the checksum. This function does NOT +// validate against the BIP-173 maximum length allowed for bech32 strings and +// is meant for use in custom applications (such as lightning network payment +// requests), NOT on-chain addresses. +// +// Note that the returned data is 5-bit (base32) encoded and the human-readable +// part will be lowercase. +func DecodeNoLimit(bech string) (string, []byte, error) { + hrp, data, _, err := decodeNoLimit(bech) + return hrp, data, err +} + +// Decode decodes a bech32 encoded string, returning the human-readable part and +// the data part excluding the checksum. +// +// Note that the returned data is 5-bit (base32) encoded and the human-readable +// part will be lowercase. +func Decode(bech string) (string, []byte, error) { + // The maximum allowed length for a bech32 string is 90. + if len(bech) > 90 { + return "", nil, ErrInvalidLength(len(bech)) + } + + hrp, data, _, err := decodeNoLimit(bech) + return hrp, data, err +} + +// DecodeGeneric is identical to the existing Decode method, but will also +// return bech32 version that matches the decoded checksum. This method should +// be used when decoding segwit addresses, as it enables additional +// verification to ensure the proper checksum is used. +func DecodeGeneric(bech string) (string, []byte, Version, error) { + // The maximum allowed length for a bech32 string is 90. + if len(bech) > 90 { + return "", nil, VersionUnknown, ErrInvalidLength(len(bech)) + } + + return decodeNoLimit(bech) +} + +// encodeGeneric is the base bech32 encoding function that is aware of the +// existence of the checksum versions. This method is private, as the Encode +// and EncodeM methods are intended to be used instead. +func encodeGeneric(hrp string, data []byte, + version Version) (string, error) { + + // The resulting bech32 string is the concatenation of the lowercase + // hrp, the separator 1, data and the 6-byte checksum. + hrp = strings.ToLower(hrp) + var bldr strings.Builder + bldr.Grow(len(hrp) + 1 + len(data) + 6) + bldr.WriteString(hrp) + bldr.WriteString("1") + + // Write the data part, using the bech32 charset. + for _, b := range data { + if int(b) >= len(charset) { + return "", ErrInvalidDataByte(b) + } + bldr.WriteByte(charset[b]) + } + + // Calculate and write the checksum of the data. + writeBech32Checksum(hrp, data, &bldr, version) + + return bldr.String(), nil +} + +// Encode encodes a byte slice into a bech32 string with the given +// human-readable part (HRP). The HRP will be converted to lowercase if needed +// since mixed cased encodings are not permitted and lowercase is used for +// checksum purposes. Note that the bytes must each encode 5 bits (base32). +func Encode(hrp string, data []byte) (string, error) { + return encodeGeneric(hrp, data, Version0) +} + +// EncodeM is the exactly same as the Encode method, but it uses the new +// bech32m constant instead of the original one. It should be used whenever one +// attempts to encode a segwit address of v1 and beyond. +func EncodeM(hrp string, data []byte) (string, error) { + return encodeGeneric(hrp, data, VersionM) +} + +// ConvertBits converts a byte slice where each byte is encoding fromBits bits, +// to a byte slice where each byte is encoding toBits bits. +func ConvertBits(data []byte, fromBits, toBits uint8, pad bool) ([]byte, error) { + if fromBits < 1 || fromBits > 8 || toBits < 1 || toBits > 8 { + return nil, ErrInvalidBitGroups{} + } + + // Determine the maximum size the resulting array can have after base + // conversion, so that we can size it a single time. This might be off + // by a byte depending on whether padding is used or not and if the input + // data is a multiple of both fromBits and toBits, but we ignore that and + // just size it to the maximum possible. + maxSize := len(data)*int(fromBits)/int(toBits) + 1 + + // The final bytes, each byte encoding toBits bits. + regrouped := make([]byte, 0, maxSize) + + // Keep track of the next byte we create and how many bits we have + // added to it out of the toBits goal. + nextByte := byte(0) + filledBits := uint8(0) + + for _, b := range data { + + // Discard unused bits. + b <<= 8 - fromBits + + // How many bits remaining to extract from the input data. + remFromBits := fromBits + for remFromBits > 0 { + // How many bits remaining to be added to the next byte. + remToBits := toBits - filledBits + + // The number of bytes to next extract is the minimum of + // remFromBits and remToBits. + toExtract := remFromBits + if remToBits < toExtract { + toExtract = remToBits + } + + // Add the next bits to nextByte, shifting the already + // added bits to the left. + nextByte = (nextByte << toExtract) | (b >> (8 - toExtract)) + + // Discard the bits we just extracted and get ready for + // next iteration. + b <<= toExtract + remFromBits -= toExtract + filledBits += toExtract + + // If the nextByte is completely filled, we add it to + // our regrouped bytes and start on the next byte. + if filledBits == toBits { + regrouped = append(regrouped, nextByte) + filledBits = 0 + nextByte = 0 + } + } + } + + // We pad any unfinished group if specified. + if pad && filledBits > 0 { + nextByte <<= toBits - filledBits + regrouped = append(regrouped, nextByte) + filledBits = 0 + nextByte = 0 + } + + // Any incomplete group must be <= 4 bits, and all zeroes. + if filledBits > 0 && (filledBits > 4 || nextByte != 0) { + return nil, ErrInvalidIncompleteGroup{} + } + + return regrouped, nil +} + +// EncodeFromBase256 converts a base256-encoded byte slice into a base32-encoded +// byte slice and then encodes it into a bech32 string with the given +// human-readable part (HRP). The HRP will be converted to lowercase if needed +// since mixed cased encodings are not permitted and lowercase is used for +// checksum purposes. +func EncodeFromBase256(hrp string, data []byte) (string, error) { + converted, err := ConvertBits(data, 8, 5, true) + if err != nil { + return "", err + } + return Encode(hrp, converted) +} + +// DecodeToBase256 decodes a bech32-encoded string into its associated +// human-readable part (HRP) and base32-encoded data, converts that data to a +// base256-encoded byte slice and returns it along with the lowercase HRP. +func DecodeToBase256(bech string) (string, []byte, error) { + hrp, data, err := Decode(bech) + if err != nil { + return "", nil, err + } + converted, err := ConvertBits(data, 5, 8, false) + if err != nil { + return "", nil, err + } + return hrp, converted, nil +} diff --git a/vendor/github.com/btcsuite/btcd/btcutil/bech32/doc.go b/vendor/github.com/btcsuite/btcd/btcutil/bech32/doc.go new file mode 100644 index 00000000..2d64fbe0 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcutil/bech32/doc.go @@ -0,0 +1,15 @@ +// Copyright (c) 2017 The btcsuite developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +/* +Package bech32 provides a Go implementation of the bech32 format specified in +BIP 173. + +Bech32 strings consist of a human-readable part (hrp), followed by the +separator 1, then a checksummed data part encoded using the 32 characters +"qpzry9x8gf2tvdw0s3jn54khce6mua7l". + +More info: https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki +*/ +package bech32 diff --git a/vendor/github.com/btcsuite/btcd/btcutil/bech32/error.go b/vendor/github.com/btcsuite/btcd/btcutil/bech32/error.go new file mode 100644 index 00000000..e8b1fe8c --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcutil/bech32/error.go @@ -0,0 +1,87 @@ +// Copyright (c) 2019 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package bech32 + +import ( + "fmt" +) + +// ErrMixedCase is returned when the bech32 string has both lower and uppercase +// characters. +type ErrMixedCase struct{} + +func (e ErrMixedCase) Error() string { + return "string not all lowercase or all uppercase" +} + +// ErrInvalidBitGroups is returned when conversion is attempted between byte +// slices using bit-per-element of unsupported value. +type ErrInvalidBitGroups struct{} + +func (e ErrInvalidBitGroups) Error() string { + return "only bit groups between 1 and 8 allowed" +} + +// ErrInvalidIncompleteGroup is returned when then byte slice used as input has +// data of wrong length. +type ErrInvalidIncompleteGroup struct{} + +func (e ErrInvalidIncompleteGroup) Error() string { + return "invalid incomplete group" +} + +// ErrInvalidLength is returned when the bech32 string has an invalid length +// given the BIP-173 defined restrictions. +type ErrInvalidLength int + +func (e ErrInvalidLength) Error() string { + return fmt.Sprintf("invalid bech32 string length %d", int(e)) +} + +// ErrInvalidCharacter is returned when the bech32 string has a character +// outside the range of the supported charset. +type ErrInvalidCharacter rune + +func (e ErrInvalidCharacter) Error() string { + return fmt.Sprintf("invalid character in string: '%c'", rune(e)) +} + +// ErrInvalidSeparatorIndex is returned when the separator character '1' is +// in an invalid position in the bech32 string. +type ErrInvalidSeparatorIndex int + +func (e ErrInvalidSeparatorIndex) Error() string { + return fmt.Sprintf("invalid separator index %d", int(e)) +} + +// ErrNonCharsetChar is returned when a character outside of the specific +// bech32 charset is used in the string. +type ErrNonCharsetChar rune + +func (e ErrNonCharsetChar) Error() string { + return fmt.Sprintf("invalid character not part of charset: %v", int(e)) +} + +// ErrInvalidChecksum is returned when the extracted checksum of the string +// is different than what was expected. Both the original version, as well as +// the new bech32m checksum may be specified. +type ErrInvalidChecksum struct { + Expected string + ExpectedM string + Actual string +} + +func (e ErrInvalidChecksum) Error() string { + return fmt.Sprintf("invalid checksum (expected (bech32=%v, "+ + "bech32m=%v), got %v)", e.Expected, e.ExpectedM, e.Actual) +} + +// ErrInvalidDataByte is returned when a byte outside the range required for +// conversion into a string was found. +type ErrInvalidDataByte byte + +func (e ErrInvalidDataByte) Error() string { + return fmt.Sprintf("invalid data byte: %v", byte(e)) +} diff --git a/vendor/github.com/btcsuite/btcd/btcutil/bech32/version.go b/vendor/github.com/btcsuite/btcd/btcutil/bech32/version.go new file mode 100644 index 00000000..147037db --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/btcutil/bech32/version.go @@ -0,0 +1,43 @@ +package bech32 + +// ChecksumConst is a type that represents the currently defined bech32 +// checksum constants. +type ChecksumConst int + +const ( + // Version0Const is the original constant used in the checksum + // verification for bech32. + Version0Const ChecksumConst = 1 + + // VersionMConst is the new constant used for bech32m checksum + // verification. + VersionMConst ChecksumConst = 0x2bc830a3 +) + +// Version defines the current set of bech32 versions. +type Version uint8 + +const ( + // Version0 defines the original bech version. + Version0 Version = iota + + // VersionM is the new bech32 version defined in BIP-350, also known as + // bech32m. + VersionM + + // VersionUnknown denotes an unknown bech version. + VersionUnknown +) + +// VersionToConsts maps bech32 versions to the checksum constant to be used +// when encoding, and asserting a particular version when decoding. +var VersionToConsts = map[Version]ChecksumConst{ + Version0: Version0Const, + VersionM: VersionMConst, +} + +// ConstsToVersion maps a bech32 constant to the version it's associated with. +var ConstsToVersion = map[ChecksumConst]Version{ + Version0Const: Version0, + VersionMConst: VersionM, +} diff --git a/vendor/github.com/btcsuite/btcd/chaincfg/chainhash/LICENSE b/vendor/github.com/btcsuite/btcd/chaincfg/chainhash/LICENSE new file mode 100644 index 00000000..46dcd395 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/chaincfg/chainhash/LICENSE @@ -0,0 +1,16 @@ +ISC License + +Copyright (c) 2013-2023 The btcsuite developers +Copyright (c) 2015-2016 The Decred developers + +Permission to use, copy, modify, and distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/vendor/github.com/btcsuite/btcd/chaincfg/chainhash/README.md b/vendor/github.com/btcsuite/btcd/chaincfg/chainhash/README.md new file mode 100644 index 00000000..b7ddf19e --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/chaincfg/chainhash/README.md @@ -0,0 +1,41 @@ +chainhash +========= + +[![Build Status](https://github.com/btcsuite/btcd/workflows/Build%20and%20Test/badge.svg)](https://github.com/btcsuite/btcd/actions) +[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org) +[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](https://pkg.go.dev/github.com/btcsuite/btcd/chaincfg/chainhash) +======= + +chainhash provides a generic hash type and associated functions that allows the +specific hash algorithm to be abstracted. + +## Installation and Updating + +```bash +$ go get -u github.com/btcsuite/btcd/chaincfg/chainhash +``` + +## GPG Verification Key + +All official release tags are signed by Conformal so users can ensure the code +has not been tampered with and is coming from the btcsuite developers. To +verify the signature perform the following: + +- Download the public key from the Conformal website at + https://opensource.conformal.com/GIT-GPG-KEY-conformal.txt + +- Import the public key into your GPG keyring: + ```bash + gpg --import GIT-GPG-KEY-conformal.txt + ``` + +- Verify the release tag with the following command where `TAG_NAME` is a + placeholder for the specific tag: + ```bash + git tag -v TAG_NAME + ``` + +## License + +Package chainhash is licensed under the [copyfree](http://copyfree.org) ISC +License. diff --git a/vendor/github.com/btcsuite/btcd/chaincfg/chainhash/doc.go b/vendor/github.com/btcsuite/btcd/chaincfg/chainhash/doc.go new file mode 100644 index 00000000..c3eb43d3 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/chaincfg/chainhash/doc.go @@ -0,0 +1,5 @@ +// Package chainhash provides abstracted hash functionality. +// +// This package provides a generic hash type and associated functions that +// allows the specific hash algorithm to be abstracted. +package chainhash diff --git a/vendor/github.com/btcsuite/btcd/chaincfg/chainhash/hash.go b/vendor/github.com/btcsuite/btcd/chaincfg/chainhash/hash.go new file mode 100644 index 00000000..4aa7aeb6 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/chaincfg/chainhash/hash.go @@ -0,0 +1,239 @@ +// Copyright (c) 2013-2016 The btcsuite developers +// Copyright (c) 2015 The Decred developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package chainhash + +import ( + "crypto/sha256" + "encoding/hex" + "encoding/json" + "fmt" +) + +// HashSize of array used to store hashes. See Hash. +const HashSize = 32 + +// MaxHashStringSize is the maximum length of a Hash hash string. +const MaxHashStringSize = HashSize * 2 + +var ( + // TagBIP0340Challenge is the BIP-0340 tag for challenges. + TagBIP0340Challenge = []byte("BIP0340/challenge") + + // TagBIP0340Aux is the BIP-0340 tag for aux data. + TagBIP0340Aux = []byte("BIP0340/aux") + + // TagBIP0340Nonce is the BIP-0340 tag for nonces. + TagBIP0340Nonce = []byte("BIP0340/nonce") + + // TagTapSighash is the tag used by BIP 341 to generate the sighash + // flags. + TagTapSighash = []byte("TapSighash") + + // TagTagTapLeaf is the message tag prefix used to compute the hash + // digest of a tapscript leaf. + TagTapLeaf = []byte("TapLeaf") + + // TagTapBranch is the message tag prefix used to compute the + // hash digest of two tap leaves into a taproot branch node. + TagTapBranch = []byte("TapBranch") + + // TagTapTweak is the message tag prefix used to compute the hash tweak + // used to enable a public key to commit to the taproot branch root + // for the witness program. + TagTapTweak = []byte("TapTweak") + + // precomputedTags is a map containing the SHA-256 hash of the BIP-0340 + // tags. + precomputedTags = map[string]Hash{ + string(TagBIP0340Challenge): sha256.Sum256(TagBIP0340Challenge), + string(TagBIP0340Aux): sha256.Sum256(TagBIP0340Aux), + string(TagBIP0340Nonce): sha256.Sum256(TagBIP0340Nonce), + string(TagTapSighash): sha256.Sum256(TagTapSighash), + string(TagTapLeaf): sha256.Sum256(TagTapLeaf), + string(TagTapBranch): sha256.Sum256(TagTapBranch), + string(TagTapTweak): sha256.Sum256(TagTapTweak), + } +) + +// ErrHashStrSize describes an error that indicates the caller specified a hash +// string that has too many characters. +var ErrHashStrSize = fmt.Errorf("max hash string length is %v bytes", MaxHashStringSize) + +// Hash is used in several of the bitcoin messages and common structures. It +// typically represents the double sha256 of data. +type Hash [HashSize]byte + +// String returns the Hash as the hexadecimal string of the byte-reversed +// hash. +func (hash Hash) String() string { + for i := 0; i < HashSize/2; i++ { + hash[i], hash[HashSize-1-i] = hash[HashSize-1-i], hash[i] + } + return hex.EncodeToString(hash[:]) +} + +// CloneBytes returns a copy of the bytes which represent the hash as a byte +// slice. +// +// NOTE: It is generally cheaper to just slice the hash directly thereby reusing +// the same bytes rather than calling this method. +func (hash *Hash) CloneBytes() []byte { + newHash := make([]byte, HashSize) + copy(newHash, hash[:]) + + return newHash +} + +// SetBytes sets the bytes which represent the hash. An error is returned if +// the number of bytes passed in is not HashSize. +func (hash *Hash) SetBytes(newHash []byte) error { + nhlen := len(newHash) + if nhlen != HashSize { + return fmt.Errorf("invalid hash length of %v, want %v", nhlen, + HashSize) + } + copy(hash[:], newHash) + + return nil +} + +// IsEqual returns true if target is the same as hash. +func (hash *Hash) IsEqual(target *Hash) bool { + if hash == nil && target == nil { + return true + } + if hash == nil || target == nil { + return false + } + return *hash == *target +} + +// MarshalJSON serialises the hash as a JSON appropriate string value. +func (hash Hash) MarshalJSON() ([]byte, error) { + return json.Marshal(hash.String()) +} + +// UnmarshalJSON parses the hash with JSON appropriate string value. +func (hash *Hash) UnmarshalJSON(input []byte) error { + // If the first byte indicates an array, the hash could have been marshalled + // using the legacy method and e.g. persisted. + if len(input) > 0 && input[0] == '[' { + return decodeLegacy(hash, input) + } + + var sh string + err := json.Unmarshal(input, &sh) + if err != nil { + return err + } + newHash, err := NewHashFromStr(sh) + if err != nil { + return err + } + + return hash.SetBytes(newHash[:]) +} + +// NewHash returns a new Hash from a byte slice. An error is returned if +// the number of bytes passed in is not HashSize. +func NewHash(newHash []byte) (*Hash, error) { + var sh Hash + err := sh.SetBytes(newHash) + if err != nil { + return nil, err + } + return &sh, err +} + +// TaggedHash implements the tagged hash scheme described in BIP-340. We use +// sha-256 to bind a message hash to a specific context using a tag: +// sha256(sha256(tag) || sha256(tag) || msg). +func TaggedHash(tag []byte, msgs ...[]byte) *Hash { + // Check to see if we've already pre-computed the hash of the tag. If + // so then this'll save us an extra sha256 hash. + shaTag, ok := precomputedTags[string(tag)] + if !ok { + shaTag = sha256.Sum256(tag) + } + + // h = sha256(sha256(tag) || sha256(tag) || msg) + h := sha256.New() + h.Write(shaTag[:]) + h.Write(shaTag[:]) + + for _, msg := range msgs { + h.Write(msg) + } + + taggedHash := h.Sum(nil) + + // The function can't error out since the above hash is guaranteed to + // be 32 bytes. + hash, _ := NewHash(taggedHash) + + return hash +} + +// NewHashFromStr creates a Hash from a hash string. The string should be +// the hexadecimal string of a byte-reversed hash, but any missing characters +// result in zero padding at the end of the Hash. +func NewHashFromStr(hash string) (*Hash, error) { + ret := new(Hash) + err := Decode(ret, hash) + if err != nil { + return nil, err + } + return ret, nil +} + +// Decode decodes the byte-reversed hexadecimal string encoding of a Hash to a +// destination. +func Decode(dst *Hash, src string) error { + // Return error if hash string is too long. + if len(src) > MaxHashStringSize { + return ErrHashStrSize + } + + // Hex decoder expects the hash to be a multiple of two. When not, pad + // with a leading zero. + var srcBytes []byte + if len(src)%2 == 0 { + srcBytes = []byte(src) + } else { + srcBytes = make([]byte, 1+len(src)) + srcBytes[0] = '0' + copy(srcBytes[1:], src) + } + + // Hex decode the source bytes to a temporary destination. + var reversedHash Hash + _, err := hex.Decode(reversedHash[HashSize-hex.DecodedLen(len(srcBytes)):], srcBytes) + if err != nil { + return err + } + + // Reverse copy from the temporary hash to destination. Because the + // temporary was zeroed, the written result will be correctly padded. + for i, b := range reversedHash[:HashSize/2] { + dst[i], dst[HashSize-1-i] = reversedHash[HashSize-1-i], b + } + + return nil +} + +// decodeLegacy decodes an Hash that has been encoded with the legacy method +// (i.e. represented as a bytes array) to a destination. +func decodeLegacy(dst *Hash, src []byte) error { + var hashBytes []byte + err := json.Unmarshal(src, &hashBytes) + if err != nil { + return err + } + if len(hashBytes) != HashSize { + return ErrHashStrSize + } + return dst.SetBytes(hashBytes) +} diff --git a/vendor/github.com/btcsuite/btcd/chaincfg/chainhash/hashfuncs.go b/vendor/github.com/btcsuite/btcd/chaincfg/chainhash/hashfuncs.go new file mode 100644 index 00000000..5be8a4d4 --- /dev/null +++ b/vendor/github.com/btcsuite/btcd/chaincfg/chainhash/hashfuncs.go @@ -0,0 +1,57 @@ +// Copyright (c) 2015 The Decred developers +// Copyright (c) 2016-2017 The btcsuite developers +// Use of this source code is governed by an ISC +// license that can be found in the LICENSE file. + +package chainhash + +import ( + "crypto/sha256" + "io" +) + +// HashB calculates hash(b) and returns the resulting bytes. +func HashB(b []byte) []byte { + hash := sha256.Sum256(b) + return hash[:] +} + +// HashH calculates hash(b) and returns the resulting bytes as a Hash. +func HashH(b []byte) Hash { + return Hash(sha256.Sum256(b)) +} + +// DoubleHashB calculates hash(hash(b)) and returns the resulting bytes. +func DoubleHashB(b []byte) []byte { + first := sha256.Sum256(b) + second := sha256.Sum256(first[:]) + return second[:] +} + +// DoubleHashH calculates hash(hash(b)) and returns the resulting bytes as a +// Hash. +func DoubleHashH(b []byte) Hash { + first := sha256.Sum256(b) + return Hash(sha256.Sum256(first[:])) +} + +// DoubleHashRaw calculates hash(hash(w)) where w is the resulting bytes from +// the given serialize function and returns the resulting bytes as a Hash. +func DoubleHashRaw(serialize func(w io.Writer) error) Hash { + // Encode the transaction into the hash. Ignore the error returns + // since the only way the encode could fail is being out of memory + // or due to nil pointers, both of which would cause a run-time panic. + h := sha256.New() + _ = serialize(h) + + // This buf is here because Sum() will append the result to the passed + // in byte slice. Pre-allocating here saves an allocation on the second + // hash as we can reuse it. This allocation also does not escape to the + // heap, saving an allocation. + buf := make([]byte, 0, HashSize) + first := h.Sum(buf) + h.Reset() + h.Write(first) + res := h.Sum(buf) + return *(*Hash)(res) +} diff --git a/vendor/github.com/bytedance/sonic/LICENSE b/vendor/github.com/bytedance/sonic/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/vendor/github.com/bytedance/sonic/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/github.com/bytedance/sonic/ast/api.go b/vendor/github.com/bytedance/sonic/ast/api.go new file mode 100644 index 00000000..36151f27 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/ast/api.go @@ -0,0 +1,135 @@ +//go:build (amd64 && go1.17 && !go1.25) || (arm64 && go1.20 && !go1.25) +// +build amd64,go1.17,!go1.25 arm64,go1.20,!go1.25 + +/* + * Copyright 2022 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ast + +import ( + `runtime` + `unsafe` + + `github.com/bytedance/sonic/encoder` + `github.com/bytedance/sonic/internal/native` + `github.com/bytedance/sonic/internal/native/types` + `github.com/bytedance/sonic/internal/rt` + uq `github.com/bytedance/sonic/unquote` + `github.com/bytedance/sonic/utf8` +) + +var typeByte = rt.UnpackEface(byte(0)).Type + +//go:nocheckptr +func quote(buf *[]byte, val string) { + *buf = append(*buf, '"') + if len(val) == 0 { + *buf = append(*buf, '"') + return + } + + sp := rt.IndexChar(val, 0) + nb := len(val) + b := (*rt.GoSlice)(unsafe.Pointer(buf)) + + // input buffer + for nb > 0 { + // output buffer + dp := unsafe.Pointer(uintptr(b.Ptr) + uintptr(b.Len)) + dn := b.Cap - b.Len + // call native.Quote, dn is byte count it outputs + ret := native.Quote(sp, nb, dp, &dn, 0) + // update *buf length + b.Len += dn + + // no need more output + if ret >= 0 { + break + } + + // double buf size + *b = rt.GrowSlice(typeByte, *b, b.Cap*2) + // ret is the complement of consumed input + ret = ^ret + // update input buffer + nb -= ret + sp = unsafe.Pointer(uintptr(sp) + uintptr(ret)) + } + + runtime.KeepAlive(buf) + runtime.KeepAlive(sp) + *buf = append(*buf, '"') +} + +func unquote(src string) (string, types.ParsingError) { + return uq.String(src) +} + +func (self *Parser) decodeValue() (val types.JsonState) { + sv := (*rt.GoString)(unsafe.Pointer(&self.s)) + flag := types.F_USE_NUMBER + if self.dbuf != nil { + flag = 0 + val.Dbuf = self.dbuf + val.Dcap = types.MaxDigitNums + } + self.p = native.Value(sv.Ptr, sv.Len, self.p, &val, uint64(flag)) + return +} + +func (self *Parser) skip() (int, types.ParsingError) { + fsm := types.NewStateMachine() + start := native.SkipOne(&self.s, &self.p, fsm, 0) + types.FreeStateMachine(fsm) + + if start < 0 { + return self.p, types.ParsingError(-start) + } + return start, 0 +} + +func (self *Node) encodeInterface(buf *[]byte) error { + //WARN: NOT compatible with json.Encoder + return encoder.EncodeInto(buf, self.packAny(), encoder.NoEncoderNewline) +} + +func (self *Parser) skipFast() (int, types.ParsingError) { + start := native.SkipOneFast(&self.s, &self.p) + if start < 0 { + return self.p, types.ParsingError(-start) + } + return start, 0 +} + +func (self *Parser) getByPath(validate bool, path ...interface{}) (int, types.ParsingError) { + var fsm *types.StateMachine + if validate { + fsm = types.NewStateMachine() + } + start := native.GetByPath(&self.s, &self.p, &path, fsm) + if validate { + types.FreeStateMachine(fsm) + } + runtime.KeepAlive(path) + if start < 0 { + return self.p, types.ParsingError(-start) + } + return start, 0 +} + +func validate_utf8(str string) bool { + return utf8.ValidateString(str) +} diff --git a/vendor/github.com/bytedance/sonic/ast/api_compat.go b/vendor/github.com/bytedance/sonic/ast/api_compat.go new file mode 100644 index 00000000..74119fed --- /dev/null +++ b/vendor/github.com/bytedance/sonic/ast/api_compat.go @@ -0,0 +1,115 @@ +// +build !amd64,!arm64 go1.25 !go1.17 arm64,!go1.20 + +/* +* Copyright 2022 ByteDance Inc. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package ast + +import ( + `encoding/json` + `unicode/utf8` + + `github.com/bytedance/sonic/internal/native/types` + `github.com/bytedance/sonic/internal/rt` + `github.com/bytedance/sonic/internal/compat` +) + +func init() { + compat.Warn("sonic/ast") +} + +func quote(buf *[]byte, val string) { + quoteString(buf, val) +} + +// unquote unescapes an internal JSON string (it doesn't count quotas at the beginning and end) +func unquote(src string) (string, types.ParsingError) { + sp := rt.IndexChar(src, -1) + out, ok := unquoteBytes(rt.BytesFrom(sp, len(src)+2, len(src)+2)) + if !ok { + return "", types.ERR_INVALID_ESCAPE + } + return rt.Mem2Str(out), 0 +} + + +func (self *Parser) decodeValue() (val types.JsonState) { + e, v := decodeValue(self.s, self.p, self.dbuf == nil) + if e < 0 { + return v + } + self.p = e + return v +} + +func (self *Parser) skip() (int, types.ParsingError) { + e, s := skipValue(self.s, self.p) + if e < 0 { + return self.p, types.ParsingError(-e) + } + self.p = e + return s, 0 +} + +func (self *Parser) skipFast() (int, types.ParsingError) { + e, s := skipValueFast(self.s, self.p) + if e < 0 { + return self.p, types.ParsingError(-e) + } + self.p = e + return s, 0 +} + +func (self *Node) encodeInterface(buf *[]byte) error { + out, err := json.Marshal(self.packAny()) + if err != nil { + return err + } + *buf = append(*buf, out...) + return nil +} + +func (self *Parser) getByPath(validate bool, path ...interface{}) (int, types.ParsingError) { + for _, p := range path { + if idx, ok := p.(int); ok && idx >= 0 { + if err := self.searchIndex(idx); err != 0 { + return self.p, err + } + } else if key, ok := p.(string); ok { + if err := self.searchKey(key); err != 0 { + return self.p, err + } + } else { + panic("path must be either int(>=0) or string") + } + } + + var start int + var e types.ParsingError + if validate { + start, e = self.skip() + } else { + start, e = self.skipFast() + } + if e != 0 { + return self.p, e + } + return start, 0 +} + +func validate_utf8(str string) bool { + return utf8.ValidString(str) +} diff --git a/vendor/github.com/bytedance/sonic/ast/asm.s b/vendor/github.com/bytedance/sonic/ast/asm.s new file mode 100644 index 00000000..e69de29b diff --git a/vendor/github.com/bytedance/sonic/ast/buffer.go b/vendor/github.com/bytedance/sonic/ast/buffer.go new file mode 100644 index 00000000..04701ef5 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/ast/buffer.go @@ -0,0 +1,470 @@ +/** + * Copyright 2023 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ast + +import ( + "sort" + "unsafe" + + "github.com/bytedance/sonic/internal/caching" +) + +type nodeChunk [_DEFAULT_NODE_CAP]Node + +type linkedNodes struct { + head nodeChunk + tail []*nodeChunk + size int +} + +func (self *linkedNodes) Cap() int { + if self == nil { + return 0 + } + return (len(self.tail)+1)*_DEFAULT_NODE_CAP +} + +func (self *linkedNodes) Len() int { + if self == nil { + return 0 + } + return self.size +} + +func (self *linkedNodes) At(i int) (*Node) { + if self == nil { + return nil + } + if i >= 0 && i= _DEFAULT_NODE_CAP && i= self.size || target < 0 || target >= self.size { + return + } + // reserve source + n := *self.At(source) + if source < target { + // move every element (source,target] one step back + for i:=source; itarget; i-- { + *self.At(i) = *self.At(i-1) + } + } + // set target + *self.At(target) = n +} + +func (self *linkedNodes) Pop() { + if self == nil || self.size == 0 { + return + } + self.Set(self.size-1, Node{}) + self.size-- +} + +func (self *linkedNodes) Push(v Node) { + self.Set(self.size, v) +} + + +func (self *linkedNodes) Set(i int, v Node) { + if i < _DEFAULT_NODE_CAP { + self.head[i] = v + if self.size <= i { + self.size = i+1 + } + return + } + a, b := i/_DEFAULT_NODE_CAP-1, i%_DEFAULT_NODE_CAP + if a < 0 { + self.head[b] = v + } else { + self.growTailLength(a+1) + var n = &self.tail[a] + if *n == nil { + *n = new(nodeChunk) + } + (*n)[b] = v + } + if self.size <= i { + self.size = i+1 + } +} + +func (self *linkedNodes) growTailLength(l int) { + if l <= len(self.tail) { + return + } + c := cap(self.tail) + for c < l { + c += 1 + c>>_APPEND_GROW_SHIFT + } + if c == cap(self.tail) { + self.tail = self.tail[:l] + return + } + tmp := make([]*nodeChunk, l, c) + copy(tmp, self.tail) + self.tail = tmp +} + +func (self *linkedNodes) ToSlice(con []Node) { + if len(con) < self.size { + return + } + i := (self.size-1) + a, b := i/_DEFAULT_NODE_CAP-1, i%_DEFAULT_NODE_CAP + if a < 0 { + copy(con, self.head[:b+1]) + return + } else { + copy(con, self.head[:]) + con = con[_DEFAULT_NODE_CAP:] + } + + for i:=0; i>_APPEND_GROW_SHIFT + self.tail = make([]*nodeChunk, a+1, c) + } + self.tail = self.tail[:a+1] + + for i:=0; i= 0 && i < _DEFAULT_NODE_CAP && i= _DEFAULT_NODE_CAP && i>_APPEND_GROW_SHIFT + } + if c == cap(self.tail) { + self.tail = self.tail[:l] + return + } + tmp := make([]*pairChunk, l, c) + copy(tmp, self.tail) + self.tail = tmp +} + +// linear search +func (self *linkedPairs) Get(key string) (*Pair, int) { + if self.index != nil { + // fast-path + i, ok := self.index[caching.StrHash(key)] + if ok { + n := self.At(i) + if n.Key == key { + return n, i + } + // hash conflicts + goto linear_search + } else { + return nil, -1 + } + } +linear_search: + for i:=0; i>_APPEND_GROW_SHIFT + self.tail = make([]*pairChunk, a+1, c) + } + self.tail = self.tail[:a+1] + + for i:=0; i len(b) { + l = len(b) + } + for i := d; i < l; i++ { + if a[i] == b[i] { + continue + } + return a[i] < b[i] + } + return len(a) < len(b) +} + +type parseObjectStack struct { + parser Parser + v linkedPairs +} + +type parseArrayStack struct { + parser Parser + v linkedNodes +} + +func newLazyArray(p *Parser) Node { + s := new(parseArrayStack) + s.parser = *p + return Node{ + t: _V_ARRAY_LAZY, + p: unsafe.Pointer(s), + } +} + +func newLazyObject(p *Parser) Node { + s := new(parseObjectStack) + s.parser = *p + return Node{ + t: _V_OBJECT_LAZY, + p: unsafe.Pointer(s), + } +} + +func (self *Node) getParserAndArrayStack() (*Parser, *parseArrayStack) { + stack := (*parseArrayStack)(self.p) + return &stack.parser, stack +} + +func (self *Node) getParserAndObjectStack() (*Parser, *parseObjectStack) { + stack := (*parseObjectStack)(self.p) + return &stack.parser, stack +} + diff --git a/vendor/github.com/bytedance/sonic/ast/decode.go b/vendor/github.com/bytedance/sonic/ast/decode.go new file mode 100644 index 00000000..135ee6eb --- /dev/null +++ b/vendor/github.com/bytedance/sonic/ast/decode.go @@ -0,0 +1,562 @@ +/* + * Copyright 2022 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ast + +import ( + "encoding/base64" + "runtime" + "strconv" + "unsafe" + + "github.com/bytedance/sonic/internal/native/types" + "github.com/bytedance/sonic/internal/rt" + "github.com/bytedance/sonic/internal/utils" +) + +// Hack: this is used for both checking space and cause friendly compile errors in 32-bit arch. +const _Sonic_Not_Support_32Bit_Arch__Checking_32Bit_Arch_Here = (1 << ' ') | (1 << '\t') | (1 << '\r') | (1 << '\n') + +var bytesNull = []byte("null") + +const ( + strNull = "null" + bytesTrue = "true" + bytesFalse = "false" + bytesObject = "{}" + bytesArray = "[]" +) + +func isSpace(c byte) bool { + return (int(1<= se { + return -int(types.ERR_EOF) + } + runtime.KeepAlive(src) + return int(sp - uintptr(rt.IndexChar(src, 0))) +} + +func decodeNull(src string, pos int) (ret int) { + ret = pos + 4 + if ret > len(src) { + return -int(types.ERR_EOF) + } + if src[pos:ret] == strNull { + return ret + } else { + return -int(types.ERR_INVALID_CHAR) + } +} + +func decodeTrue(src string, pos int) (ret int) { + ret = pos + 4 + if ret > len(src) { + return -int(types.ERR_EOF) + } + if src[pos:ret] == bytesTrue { + return ret + } else { + return -int(types.ERR_INVALID_CHAR) + } + +} + +func decodeFalse(src string, pos int) (ret int) { + ret = pos + 5 + if ret > len(src) { + return -int(types.ERR_EOF) + } + if src[pos:ret] == bytesFalse { + return ret + } + return -int(types.ERR_INVALID_CHAR) +} + +//go:nocheckptr +func decodeString(src string, pos int) (ret int, v string) { + ret, ep := skipString(src, pos) + if ep == -1 { + (*rt.GoString)(unsafe.Pointer(&v)).Ptr = rt.IndexChar(src, pos+1) + (*rt.GoString)(unsafe.Pointer(&v)).Len = ret - pos - 2 + return ret, v + } + + vv, ok := unquoteBytes(rt.Str2Mem(src[pos:ret])) + if !ok { + return -int(types.ERR_INVALID_CHAR), "" + } + + runtime.KeepAlive(src) + return ret, rt.Mem2Str(vv) +} + +func decodeBinary(src string, pos int) (ret int, v []byte) { + var vv string + ret, vv = decodeString(src, pos) + if ret < 0 { + return ret, nil + } + var err error + v, err = base64.StdEncoding.DecodeString(vv) + if err != nil { + return -int(types.ERR_INVALID_CHAR), nil + } + return ret, v +} + +func isDigit(c byte) bool { + return c >= '0' && c <= '9' +} + +//go:nocheckptr +func decodeInt64(src string, pos int) (ret int, v int64, err error) { + sp := uintptr(rt.IndexChar(src, pos)) + ss := uintptr(sp) + se := uintptr(rt.IndexChar(src, len(src))) + if uintptr(sp) >= se { + return -int(types.ERR_EOF), 0, nil + } + + if c := *(*byte)(unsafe.Pointer(sp)); c == '-' { + sp += 1 + } + if sp == se { + return -int(types.ERR_EOF), 0, nil + } + + for ; sp < se; sp += uintptr(1) { + if !isDigit(*(*byte)(unsafe.Pointer(sp))) { + break + } + } + + if sp < se { + if c := *(*byte)(unsafe.Pointer(sp)); c == '.' || c == 'e' || c == 'E' { + return -int(types.ERR_INVALID_NUMBER_FMT), 0, nil + } + } + + var vv string + ret = int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr)) + (*rt.GoString)(unsafe.Pointer(&vv)).Ptr = unsafe.Pointer(ss) + (*rt.GoString)(unsafe.Pointer(&vv)).Len = ret - pos + + v, err = strconv.ParseInt(vv, 10, 64) + if err != nil { + //NOTICE: allow overflow here + if err.(*strconv.NumError).Err == strconv.ErrRange { + return ret, 0, err + } + return -int(types.ERR_INVALID_CHAR), 0, err + } + + runtime.KeepAlive(src) + return ret, v, nil +} + +func isNumberChars(c byte) bool { + return (c >= '0' && c <= '9') || c == '+' || c == '-' || c == 'e' || c == 'E' || c == '.' +} + +//go:nocheckptr +func decodeFloat64(src string, pos int) (ret int, v float64, err error) { + sp := uintptr(rt.IndexChar(src, pos)) + ss := uintptr(sp) + se := uintptr(rt.IndexChar(src, len(src))) + if uintptr(sp) >= se { + return -int(types.ERR_EOF), 0, nil + } + + if c := *(*byte)(unsafe.Pointer(sp)); c == '-' { + sp += 1 + } + if sp == se { + return -int(types.ERR_EOF), 0, nil + } + + for ; sp < se; sp += uintptr(1) { + if !isNumberChars(*(*byte)(unsafe.Pointer(sp))) { + break + } + } + + var vv string + ret = int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr)) + (*rt.GoString)(unsafe.Pointer(&vv)).Ptr = unsafe.Pointer(ss) + (*rt.GoString)(unsafe.Pointer(&vv)).Len = ret - pos + + v, err = strconv.ParseFloat(vv, 64) + if err != nil { + //NOTICE: allow overflow here + if err.(*strconv.NumError).Err == strconv.ErrRange { + return ret, 0, err + } + return -int(types.ERR_INVALID_CHAR), 0, err + } + + runtime.KeepAlive(src) + return ret, v, nil +} + +func decodeValue(src string, pos int, skipnum bool) (ret int, v types.JsonState) { + pos = skipBlank(src, pos) + if pos < 0 { + return pos, types.JsonState{Vt: types.ValueType(pos)} + } + switch c := src[pos]; c { + case 'n': + ret = decodeNull(src, pos) + if ret < 0 { + return ret, types.JsonState{Vt: types.ValueType(ret)} + } + return ret, types.JsonState{Vt: types.V_NULL} + case '"': + var ep int + ret, ep = skipString(src, pos) + if ret < 0 { + return ret, types.JsonState{Vt: types.ValueType(ret)} + } + return ret, types.JsonState{Vt: types.V_STRING, Iv: int64(pos + 1), Ep: ep} + case '{': + return pos + 1, types.JsonState{Vt: types.V_OBJECT} + case '[': + return pos + 1, types.JsonState{Vt: types.V_ARRAY} + case 't': + ret = decodeTrue(src, pos) + if ret < 0 { + return ret, types.JsonState{Vt: types.ValueType(ret)} + } + return ret, types.JsonState{Vt: types.V_TRUE} + case 'f': + ret = decodeFalse(src, pos) + if ret < 0 { + return ret, types.JsonState{Vt: types.ValueType(ret)} + } + return ret, types.JsonState{Vt: types.V_FALSE} + case '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + if skipnum { + ret = skipNumber(src, pos) + if ret >= 0 { + return ret, types.JsonState{Vt: types.V_DOUBLE, Iv: 0, Ep: pos} + } else { + return ret, types.JsonState{Vt: types.ValueType(ret)} + } + } else { + var iv int64 + ret, iv, _ = decodeInt64(src, pos) + if ret >= 0 { + return ret, types.JsonState{Vt: types.V_INTEGER, Iv: iv, Ep: pos} + } else if ret != -int(types.ERR_INVALID_NUMBER_FMT) { + return ret, types.JsonState{Vt: types.ValueType(ret)} + } + var fv float64 + ret, fv, _ = decodeFloat64(src, pos) + if ret >= 0 { + return ret, types.JsonState{Vt: types.V_DOUBLE, Dv: fv, Ep: pos} + } else { + return ret, types.JsonState{Vt: types.ValueType(ret)} + } + } + + default: + return -int(types.ERR_INVALID_CHAR), types.JsonState{Vt:-types.ValueType(types.ERR_INVALID_CHAR)} + } +} + +//go:nocheckptr +func skipNumber(src string, pos int) (ret int) { + return utils.SkipNumber(src, pos) +} + +//go:nocheckptr +func skipString(src string, pos int) (ret int, ep int) { + if pos+1 >= len(src) { + return -int(types.ERR_EOF), -1 + } + + sp := uintptr(rt.IndexChar(src, pos)) + se := uintptr(rt.IndexChar(src, len(src))) + + // not start with quote + if *(*byte)(unsafe.Pointer(sp)) != '"' { + return -int(types.ERR_INVALID_CHAR), -1 + } + sp += 1 + + ep = -1 + for sp < se { + c := *(*byte)(unsafe.Pointer(sp)) + if c == '\\' { + if ep == -1 { + ep = int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr)) + } + sp += 2 + continue + } + sp += 1 + if c == '"' { + return int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr)), ep + } + } + + runtime.KeepAlive(src) + // not found the closed quote until EOF + return -int(types.ERR_EOF), -1 +} + +//go:nocheckptr +func skipPair(src string, pos int, lchar byte, rchar byte) (ret int) { + if pos+1 >= len(src) { + return -int(types.ERR_EOF) + } + + sp := uintptr(rt.IndexChar(src, pos)) + se := uintptr(rt.IndexChar(src, len(src))) + + if *(*byte)(unsafe.Pointer(sp)) != lchar { + return -int(types.ERR_INVALID_CHAR) + } + + sp += 1 + nbrace := 1 + inquote := false + + for sp < se { + c := *(*byte)(unsafe.Pointer(sp)) + if c == '\\' { + sp += 2 + continue + } else if c == '"' { + inquote = !inquote + } else if c == lchar { + if !inquote { + nbrace += 1 + } + } else if c == rchar { + if !inquote { + nbrace -= 1 + if nbrace == 0 { + sp += 1 + break + } + } + } + sp += 1 + } + + if nbrace != 0 { + return -int(types.ERR_INVALID_CHAR) + } + + runtime.KeepAlive(src) + return int(uintptr(sp) - uintptr((*rt.GoString)(unsafe.Pointer(&src)).Ptr)) +} + +func skipValueFast(src string, pos int) (ret int, start int) { + pos = skipBlank(src, pos) + if pos < 0 { + return pos, -1 + } + switch c := src[pos]; c { + case 'n': + ret = decodeNull(src, pos) + case '"': + ret, _ = skipString(src, pos) + case '{': + ret = skipPair(src, pos, '{', '}') + case '[': + ret = skipPair(src, pos, '[', ']') + case 't': + ret = decodeTrue(src, pos) + case 'f': + ret = decodeFalse(src, pos) + case '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + ret = skipNumber(src, pos) + default: + ret = -int(types.ERR_INVALID_CHAR) + } + return ret, pos +} + +func skipValue(src string, pos int) (ret int, start int) { + pos = skipBlank(src, pos) + if pos < 0 { + return pos, -1 + } + switch c := src[pos]; c { + case 'n': + ret = decodeNull(src, pos) + case '"': + ret, _ = skipString(src, pos) + case '{': + ret, _ = skipObject(src, pos) + case '[': + ret, _ = skipArray(src, pos) + case 't': + ret = decodeTrue(src, pos) + case 'f': + ret = decodeFalse(src, pos) + case '-', '+', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + ret = skipNumber(src, pos) + default: + ret = -int(types.ERR_INVALID_CHAR) + } + return ret, pos +} + +func skipObject(src string, pos int) (ret int, start int) { + start = skipBlank(src, pos) + if start < 0 { + return start, -1 + } + + if src[start] != '{' { + return -int(types.ERR_INVALID_CHAR), -1 + } + + pos = start + 1 + pos = skipBlank(src, pos) + if pos < 0 { + return pos, -1 + } + if src[pos] == '}' { + return pos + 1, start + } + + for { + pos, _ = skipString(src, pos) + if pos < 0 { + return pos, -1 + } + + pos = skipBlank(src, pos) + if pos < 0 { + return pos, -1 + } + if src[pos] != ':' { + return -int(types.ERR_INVALID_CHAR), -1 + } + + pos++ + pos, _ = skipValue(src, pos) + if pos < 0 { + return pos, -1 + } + + pos = skipBlank(src, pos) + if pos < 0 { + return pos, -1 + } + if src[pos] == '}' { + return pos + 1, start + } + if src[pos] != ',' { + return -int(types.ERR_INVALID_CHAR), -1 + } + + pos++ + pos = skipBlank(src, pos) + if pos < 0 { + return pos, -1 + } + + } +} + +func skipArray(src string, pos int) (ret int, start int) { + start = skipBlank(src, pos) + if start < 0 { + return start, -1 + } + + if src[start] != '[' { + return -int(types.ERR_INVALID_CHAR), -1 + } + + pos = start + 1 + pos = skipBlank(src, pos) + if pos < 0 { + return pos, -1 + } + if src[pos] == ']' { + return pos + 1, start + } + + for { + pos, _ = skipValue(src, pos) + if pos < 0 { + return pos, -1 + } + + pos = skipBlank(src, pos) + if pos < 0 { + return pos, -1 + } + if src[pos] == ']' { + return pos + 1, start + } + if src[pos] != ',' { + return -int(types.ERR_INVALID_CHAR), -1 + } + pos++ + } +} + +// DecodeString decodes a JSON string from pos and return golang string. +// - needEsc indicates if to unescaped escaping chars +// - hasEsc tells if the returned string has escaping chars +// - validStr enables validating UTF8 charset +// +func _DecodeString(src string, pos int, needEsc bool, validStr bool) (v string, ret int, hasEsc bool) { + p := NewParserObj(src) + p.p = pos + switch val := p.decodeValue(); val.Vt { + case types.V_STRING: + str := p.s[val.Iv : p.p-1] + if validStr && !validate_utf8(str) { + return "", -int(types.ERR_INVALID_UTF8), false + } + /* fast path: no escape sequence */ + if val.Ep == -1 { + return str, p.p, false + } else if !needEsc { + return str, p.p, true + } + /* unquote the string */ + out, err := unquote(str) + /* check for errors */ + if err != 0 { + return "", -int(err), true + } else { + return out, p.p, true + } + default: + return "", -int(_ERR_UNSUPPORT_TYPE), false + } +} diff --git a/vendor/github.com/bytedance/sonic/ast/encode.go b/vendor/github.com/bytedance/sonic/ast/encode.go new file mode 100644 index 00000000..eae0bd25 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/ast/encode.go @@ -0,0 +1,274 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ast + +import ( + "sync" + "unicode/utf8" + + "github.com/bytedance/sonic/internal/rt" + "github.com/bytedance/sonic/option" +) + +func quoteString(e *[]byte, s string) { + *e = append(*e, '"') + start := 0 + for i := 0; i < len(s); { + if b := s[i]; b < utf8.RuneSelf { + if rt.SafeSet[b] { + i++ + continue + } + if start < i { + *e = append(*e, s[start:i]...) + } + *e = append(*e, '\\') + switch b { + case '\\', '"': + *e = append(*e, b) + case '\n': + *e = append(*e, 'n') + case '\r': + *e = append(*e, 'r') + case '\t': + *e = append(*e, 't') + default: + // This encodes bytes < 0x20 except for \t, \n and \r. + // If escapeHTML is set, it also escapes <, >, and & + // because they can lead to security holes when + // user-controlled strings are rendered into JSON + // and served to some browsers. + *e = append(*e, `u00`...) + *e = append(*e, rt.Hex[b>>4]) + *e = append(*e, rt.Hex[b&0xF]) + } + i++ + start = i + continue + } + c, size := utf8.DecodeRuneInString(s[i:]) + // if c == utf8.RuneError && size == 1 { + // if start < i { + // e.Write(s[start:i]) + // } + // e.WriteString(`\ufffd`) + // i += size + // start = i + // continue + // } + if c == '\u2028' || c == '\u2029' { + if start < i { + *e = append(*e, s[start:i]...) + } + *e = append(*e, `\u202`...) + *e = append(*e, rt.Hex[c&0xF]) + i += size + start = i + continue + } + i += size + } + if start < len(s) { + *e = append(*e, s[start:]...) + } + *e = append(*e, '"') +} + +var bytesPool = sync.Pool{} + +func (self *Node) MarshalJSON() ([]byte, error) { + if self == nil { + return bytesNull, nil + } + + buf := newBuffer() + err := self.encode(buf) + if err != nil { + freeBuffer(buf) + return nil, err + } + var ret []byte + if !rt.CanSizeResue(cap(*buf)) { + ret = *buf + } else { + ret = make([]byte, len(*buf)) + copy(ret, *buf) + freeBuffer(buf) + } + return ret, err +} + +func newBuffer() *[]byte { + if ret := bytesPool.Get(); ret != nil { + return ret.(*[]byte) + } else { + buf := make([]byte, 0, option.DefaultAstBufferSize) + return &buf + } +} + +func freeBuffer(buf *[]byte) { + if !rt.CanSizeResue(cap(*buf)) { + return + } + *buf = (*buf)[:0] + bytesPool.Put(buf) +} + +func (self *Node) encode(buf *[]byte) error { + if self.isRaw() { + return self.encodeRaw(buf) + } + switch int(self.itype()) { + case V_NONE : return ErrNotExist + case V_ERROR : return self.Check() + case V_NULL : return self.encodeNull(buf) + case V_TRUE : return self.encodeTrue(buf) + case V_FALSE : return self.encodeFalse(buf) + case V_ARRAY : return self.encodeArray(buf) + case V_OBJECT: return self.encodeObject(buf) + case V_STRING: return self.encodeString(buf) + case V_NUMBER: return self.encodeNumber(buf) + case V_ANY : return self.encodeInterface(buf) + default : return ErrUnsupportType + } +} + +func (self *Node) encodeRaw(buf *[]byte) error { + lock := self.rlock() + if !self.isRaw() { + self.runlock() + return self.encode(buf) + } + raw := self.toString() + if lock { + self.runlock() + } + *buf = append(*buf, raw...) + return nil +} + +func (self *Node) encodeNull(buf *[]byte) error { + *buf = append(*buf, strNull...) + return nil +} + +func (self *Node) encodeTrue(buf *[]byte) error { + *buf = append(*buf, bytesTrue...) + return nil +} + +func (self *Node) encodeFalse(buf *[]byte) error { + *buf = append(*buf, bytesFalse...) + return nil +} + +func (self *Node) encodeNumber(buf *[]byte) error { + str := self.toString() + *buf = append(*buf, str...) + return nil +} + +func (self *Node) encodeString(buf *[]byte) error { + if self.l == 0 { + *buf = append(*buf, '"', '"') + return nil + } + + quote(buf, self.toString()) + return nil +} + +func (self *Node) encodeArray(buf *[]byte) error { + if self.isLazy() { + if err := self.skipAllIndex(); err != nil { + return err + } + } + + nb := self.len() + if nb == 0 { + *buf = append(*buf, bytesArray...) + return nil + } + + *buf = append(*buf, '[') + + var started bool + for i := 0; i < nb; i++ { + n := self.nodeAt(i) + if !n.Exists() { + continue + } + if started { + *buf = append(*buf, ',') + } + started = true + if err := n.encode(buf); err != nil { + return err + } + } + + *buf = append(*buf, ']') + return nil +} + +func (self *Pair) encode(buf *[]byte) error { + if len(*buf) == 0 { + *buf = append(*buf, '"', '"', ':') + return self.Value.encode(buf) + } + + quote(buf, self.Key) + *buf = append(*buf, ':') + + return self.Value.encode(buf) +} + +func (self *Node) encodeObject(buf *[]byte) error { + if self.isLazy() { + if err := self.skipAllKey(); err != nil { + return err + } + } + + nb := self.len() + if nb == 0 { + *buf = append(*buf, bytesObject...) + return nil + } + + *buf = append(*buf, '{') + + var started bool + for i := 0; i < nb; i++ { + n := self.pairAt(i) + if n == nil || !n.Value.Exists() { + continue + } + if started { + *buf = append(*buf, ',') + } + started = true + if err := n.encode(buf); err != nil { + return err + } + } + + *buf = append(*buf, '}') + return nil +} diff --git a/vendor/github.com/bytedance/sonic/ast/error.go b/vendor/github.com/bytedance/sonic/ast/error.go new file mode 100644 index 00000000..3716e7a9 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/ast/error.go @@ -0,0 +1,134 @@ +package ast + +import ( + `fmt` + `strings` + `unsafe` + + `github.com/bytedance/sonic/internal/native/types` +) + + +func newError(err types.ParsingError, msg string) *Node { + return &Node{ + t: V_ERROR, + l: uint(err), + p: unsafe.Pointer(&msg), + } +} + +func newErrorPair(err SyntaxError) *Pair { + return &Pair{0, "", *newSyntaxError(err)} +} + +// Error returns error message if the node is invalid +func (self Node) Error() string { + if self.t != V_ERROR { + return "" + } else { + return *(*string)(self.p) + } +} + +func newSyntaxError(err SyntaxError) *Node { + msg := err.Description() + return &Node{ + t: V_ERROR, + l: uint(err.Code), + p: unsafe.Pointer(&msg), + } +} + +func (self *Parser) syntaxError(err types.ParsingError) SyntaxError { + return SyntaxError{ + Pos : self.p, + Src : self.s, + Code: err, + } +} + +func unwrapError(err error) *Node { + if se, ok := err.(*Node); ok { + return se + }else if sse, ok := err.(Node); ok { + return &sse + } else { + msg := err.Error() + return &Node{ + t: V_ERROR, + p: unsafe.Pointer(&msg), + } + } +} + +type SyntaxError struct { + Pos int + Src string + Code types.ParsingError + Msg string +} + +func (self SyntaxError) Error() string { + return fmt.Sprintf("%q", self.Description()) +} + +func (self SyntaxError) Description() string { + return "Syntax error " + self.description() +} + +func (self SyntaxError) description() string { + i := 16 + p := self.Pos - i + q := self.Pos + i + + /* check for empty source */ + if self.Src == "" { + return fmt.Sprintf("no sources available, the input json is empty: %#v", self) + } + + /* prevent slicing before the beginning */ + if p < 0 { + p, q, i = 0, q - p, i + p + } + + /* prevent slicing beyond the end */ + if n := len(self.Src); q > n { + n = q - n + q = len(self.Src) + + /* move the left bound if possible */ + if p > n { + i += n + p -= n + } + } + + /* left and right length */ + x := clamp_zero(i) + y := clamp_zero(q - p - i - 1) + + /* compose the error description */ + return fmt.Sprintf( + "at index %d: %s\n\n\t%s\n\t%s^%s\n", + self.Pos, + self.Message(), + self.Src[p:q], + strings.Repeat(".", x), + strings.Repeat(".", y), + ) +} + +func (self SyntaxError) Message() string { + if self.Msg == "" { + return self.Code.Message() + } + return self.Msg +} + +func clamp_zero(v int) int { + if v < 0 { + return 0 + } else { + return v + } +} diff --git a/vendor/github.com/bytedance/sonic/ast/iterator.go b/vendor/github.com/bytedance/sonic/ast/iterator.go new file mode 100644 index 00000000..1052dd0a --- /dev/null +++ b/vendor/github.com/bytedance/sonic/ast/iterator.go @@ -0,0 +1,216 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ast + +import ( + "fmt" + + "github.com/bytedance/sonic/internal/caching" + "github.com/bytedance/sonic/internal/native/types" +) + +type Pair struct { + hash uint64 + Key string + Value Node +} + +func NewPair(key string, val Node) Pair { + return Pair{ + hash: caching.StrHash(key), + Key: key, + Value: val, + } +} + +// Values returns iterator for array's children traversal +func (self *Node) Values() (ListIterator, error) { + if err := self.should(types.V_ARRAY); err != nil { + return ListIterator{}, err + } + return self.values(), nil +} + +func (self *Node) values() ListIterator { + return ListIterator{Iterator{p: self}} +} + +// Properties returns iterator for object's children traversal +func (self *Node) Properties() (ObjectIterator, error) { + if err := self.should(types.V_OBJECT); err != nil { + return ObjectIterator{}, err + } + return self.properties(), nil +} + +func (self *Node) properties() ObjectIterator { + return ObjectIterator{Iterator{p: self}} +} + +type Iterator struct { + i int + p *Node +} + +func (self *Iterator) Pos() int { + return self.i +} + +func (self *Iterator) Len() int { + return self.p.len() +} + +// HasNext reports if it is the end of iteration or has error. +func (self *Iterator) HasNext() bool { + if !self.p.isLazy() { + return self.p.Valid() && self.i < self.p.len() + } else if self.p.t == _V_ARRAY_LAZY { + return self.p.skipNextNode().Valid() + } else if self.p.t == _V_OBJECT_LAZY { + pair := self.p.skipNextPair() + if pair == nil { + return false + } + return pair.Value.Valid() + } + return false +} + +// ListIterator is specialized iterator for V_ARRAY +type ListIterator struct { + Iterator +} + +// ObjectIterator is specialized iterator for V_ARRAY +type ObjectIterator struct { + Iterator +} + +func (self *ListIterator) next() *Node { +next_start: + if !self.HasNext() { + return nil + } else { + n := self.p.nodeAt(self.i) + self.i++ + if !n.Exists() { + goto next_start + } + return n + } +} + +// Next scans through children of underlying V_ARRAY, +// copies each child to v, and returns .HasNext(). +func (self *ListIterator) Next(v *Node) bool { + n := self.next() + if n == nil { + return false + } + *v = *n + return true +} + +func (self *ObjectIterator) next() *Pair { +next_start: + if !self.HasNext() { + return nil + } else { + n := self.p.pairAt(self.i) + self.i++ + if n == nil || !n.Value.Exists() { + goto next_start + } + return n + } +} + +// Next scans through children of underlying V_OBJECT, +// copies each child to v, and returns .HasNext(). +func (self *ObjectIterator) Next(p *Pair) bool { + n := self.next() + if n == nil { + return false + } + *p = *n + return true +} + +// Sequence represents scanning path of single-layer nodes. +// Index indicates the value's order in both V_ARRAY and V_OBJECT json. +// Key is the value's key (for V_OBJECT json only, otherwise it will be nil). +type Sequence struct { + Index int + Key *string + // Level int +} + +// String is string representation of one Sequence +func (s Sequence) String() string { + k := "" + if s.Key != nil { + k = *s.Key + } + return fmt.Sprintf("Sequence(%d, %q)", s.Index, k) +} + +type Scanner func(path Sequence, node *Node) bool + +// ForEach scans one V_OBJECT node's children from JSON head to tail, +// and pass the Sequence and Node of corresponding JSON value. +// +// Especially, if the node is not V_ARRAY or V_OBJECT, +// the node itself will be returned and Sequence.Index == -1. +// +// NOTICE: A unsetted node WON'T trigger sc, but its index still counts into Path.Index +func (self *Node) ForEach(sc Scanner) error { + if err := self.checkRaw(); err != nil { + return err + } + switch self.itype() { + case types.V_ARRAY: + iter, err := self.Values() + if err != nil { + return err + } + v := iter.next() + for v != nil { + if !sc(Sequence{iter.i-1, nil}, v) { + return nil + } + v = iter.next() + } + case types.V_OBJECT: + iter, err := self.Properties() + if err != nil { + return err + } + v := iter.next() + for v != nil { + if !sc(Sequence{iter.i-1, &v.Key}, &v.Value) { + return nil + } + v = iter.next() + } + default: + if self.Check() != nil { + return self + } + sc(Sequence{-1, nil}, self) + } + return nil +} diff --git a/vendor/github.com/bytedance/sonic/ast/node.go b/vendor/github.com/bytedance/sonic/ast/node.go new file mode 100644 index 00000000..17964c32 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/ast/node.go @@ -0,0 +1,1843 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ast + +import ( + "encoding/json" + "fmt" + "strconv" + "sync" + "sync/atomic" + "unsafe" + + "github.com/bytedance/sonic/internal/native/types" + "github.com/bytedance/sonic/internal/rt" +) + +const ( + _V_NONE types.ValueType = 0 + _V_NODE_BASE types.ValueType = 1 << 5 + _V_LAZY types.ValueType = 1 << 7 + _V_RAW types.ValueType = 1 << 8 + _V_NUMBER = _V_NODE_BASE + 1 + _V_ANY = _V_NODE_BASE + 2 + _V_ARRAY_LAZY = _V_LAZY | types.V_ARRAY + _V_OBJECT_LAZY = _V_LAZY | types.V_OBJECT + _MASK_LAZY = _V_LAZY - 1 + _MASK_RAW = _V_RAW - 1 +) + +const ( + V_NONE = 0 + V_ERROR = 1 + V_NULL = int(types.V_NULL) + V_TRUE = int(types.V_TRUE) + V_FALSE = int(types.V_FALSE) + V_ARRAY = int(types.V_ARRAY) + V_OBJECT = int(types.V_OBJECT) + V_STRING = int(types.V_STRING) + V_NUMBER = int(_V_NUMBER) + V_ANY = int(_V_ANY) +) + +type Node struct { + t types.ValueType + l uint + p unsafe.Pointer + m *sync.RWMutex +} + +// UnmarshalJSON is just an adapter to json.Unmarshaler. +// If you want better performance, use Searcher.GetByPath() directly +func (self *Node) UnmarshalJSON(data []byte) (err error) { + *self = NewRaw(string(data)) + return self.Check() +} + +/** Node Type Accessor **/ + +// Type returns json type represented by the node +// It will be one of bellows: +// V_NONE = 0 (empty node, key not exists) +// V_ERROR = 1 (error node) +// V_NULL = 2 (json value `null`, key exists) +// V_TRUE = 3 (json value `true`) +// V_FALSE = 4 (json value `false`) +// V_ARRAY = 5 (json value array) +// V_OBJECT = 6 (json value object) +// V_STRING = 7 (json value string) +// V_NUMBER = 33 (json value number ) +// V_ANY = 34 (golang interface{}) +// +// Deprecated: not concurrent safe. Use TypeSafe instead +func (self Node) Type() int { + return int(self.t & _MASK_LAZY & _MASK_RAW) +} + +// Type concurrently-safe returns json type represented by the node +// It will be one of bellows: +// V_NONE = 0 (empty node, key not exists) +// V_ERROR = 1 (error node) +// V_NULL = 2 (json value `null`, key exists) +// V_TRUE = 3 (json value `true`) +// V_FALSE = 4 (json value `false`) +// V_ARRAY = 5 (json value array) +// V_OBJECT = 6 (json value object) +// V_STRING = 7 (json value string) +// V_NUMBER = 33 (json value number ) +// V_ANY = 34 (golang interface{}) +func (self *Node) TypeSafe() int { + return int(self.loadt() & _MASK_LAZY & _MASK_RAW) +} + +func (self *Node) itype() types.ValueType { + return self.t & _MASK_LAZY & _MASK_RAW +} + +// Exists returns false only if the self is nil or empty node V_NONE +func (self *Node) Exists() bool { + if self == nil { + return false + } + t := self.loadt() + return t != V_ERROR && t != _V_NONE +} + +// Valid reports if self is NOT V_ERROR or nil +func (self *Node) Valid() bool { + if self == nil { + return false + } + return self.loadt() != V_ERROR +} + +// Check checks if the node itself is valid, and return: +// - ErrNotExist If the node is nil +// - Its underlying error If the node is V_ERROR +func (self *Node) Check() error { + if self == nil { + return ErrNotExist + } else if self.loadt() != V_ERROR { + return nil + } else { + return self + } +} + +// isRaw returns true if node's underlying value is raw json +// +// Deprecated: not concurrent safe +func (self Node) IsRaw() bool { + return self.t & _V_RAW != 0 +} + +// IsRaw returns true if node's underlying value is raw json +func (self *Node) isRaw() bool { + return self.loadt() & _V_RAW != 0 +} + +func (self *Node) isLazy() bool { + return self != nil && self.t & _V_LAZY != 0 +} + +func (self *Node) isAny() bool { + return self != nil && self.loadt() == _V_ANY +} + +/** Simple Value Methods **/ + +// Raw returns json representation of the node, +func (self *Node) Raw() (string, error) { + if self == nil { + return "", ErrNotExist + } + lock := self.rlock() + if !self.isRaw() { + if lock { + self.runlock() + } + buf, err := self.MarshalJSON() + return rt.Mem2Str(buf), err + } + ret := self.toString() + if lock { + self.runlock() + } + return ret, nil +} + +func (self *Node) checkRaw() error { + if err := self.Check(); err != nil { + return err + } + if self.isRaw() { + self.parseRaw(false) + } + return self.Check() +} + +// Bool returns bool value represented by this node, +// including types.V_TRUE|V_FALSE|V_NUMBER|V_STRING|V_ANY|V_NULL, +// V_NONE will return error +func (self *Node) Bool() (bool, error) { + if err := self.checkRaw(); err != nil { + return false, err + } + switch self.t { + case types.V_TRUE : return true , nil + case types.V_FALSE : return false, nil + case types.V_NULL : return false, nil + case _V_NUMBER : + if i, err := self.toInt64(); err == nil { + return i != 0, nil + } else if f, err := self.toFloat64(); err == nil { + return f != 0, nil + } else { + return false, err + } + case types.V_STRING: return strconv.ParseBool(self.toString()) + case _V_ANY : + any := self.packAny() + switch v := any.(type) { + case bool : return v, nil + case int : return v != 0, nil + case int8 : return v != 0, nil + case int16 : return v != 0, nil + case int32 : return v != 0, nil + case int64 : return v != 0, nil + case uint : return v != 0, nil + case uint8 : return v != 0, nil + case uint16 : return v != 0, nil + case uint32 : return v != 0, nil + case uint64 : return v != 0, nil + case float32: return v != 0, nil + case float64: return v != 0, nil + case string : return strconv.ParseBool(v) + case json.Number: + if i, err := v.Int64(); err == nil { + return i != 0, nil + } else if f, err := v.Float64(); err == nil { + return f != 0, nil + } else { + return false, err + } + default: return false, ErrUnsupportType + } + default : return false, ErrUnsupportType + } +} + +// Int64 casts the node to int64 value, +// including V_NUMBER|V_TRUE|V_FALSE|V_ANY|V_STRING +// V_NONE it will return error +func (self *Node) Int64() (int64, error) { + if err := self.checkRaw(); err != nil { + return 0, err + } + switch self.t { + case _V_NUMBER, types.V_STRING : + if i, err := self.toInt64(); err == nil { + return i, nil + } else if f, err := self.toFloat64(); err == nil { + return int64(f), nil + } else { + return 0, err + } + case types.V_TRUE : return 1, nil + case types.V_FALSE : return 0, nil + case types.V_NULL : return 0, nil + case _V_ANY : + any := self.packAny() + switch v := any.(type) { + case bool : if v { return 1, nil } else { return 0, nil } + case int : return int64(v), nil + case int8 : return int64(v), nil + case int16 : return int64(v), nil + case int32 : return int64(v), nil + case int64 : return int64(v), nil + case uint : return int64(v), nil + case uint8 : return int64(v), nil + case uint16 : return int64(v), nil + case uint32 : return int64(v), nil + case uint64 : return int64(v), nil + case float32: return int64(v), nil + case float64: return int64(v), nil + case string : + if i, err := strconv.ParseInt(v, 10, 64); err == nil { + return i, nil + } else if f, err := strconv.ParseFloat(v, 64); err == nil { + return int64(f), nil + } else { + return 0, err + } + case json.Number: + if i, err := v.Int64(); err == nil { + return i, nil + } else if f, err := v.Float64(); err == nil { + return int64(f), nil + } else { + return 0, err + } + default: return 0, ErrUnsupportType + } + default : return 0, ErrUnsupportType + } +} + +// StrictInt64 exports underlying int64 value, including V_NUMBER, V_ANY +func (self *Node) StrictInt64() (int64, error) { + if err := self.checkRaw(); err != nil { + return 0, err + } + switch self.t { + case _V_NUMBER : return self.toInt64() + case _V_ANY : + any := self.packAny() + switch v := any.(type) { + case int : return int64(v), nil + case int8 : return int64(v), nil + case int16 : return int64(v), nil + case int32 : return int64(v), nil + case int64 : return int64(v), nil + case uint : return int64(v), nil + case uint8 : return int64(v), nil + case uint16: return int64(v), nil + case uint32: return int64(v), nil + case uint64: return int64(v), nil + case json.Number: + if i, err := v.Int64(); err == nil { + return i, nil + } else { + return 0, err + } + default: return 0, ErrUnsupportType + } + default : return 0, ErrUnsupportType + } +} + +func castNumber(v bool) json.Number { + if v { + return json.Number("1") + } else { + return json.Number("0") + } +} + +// Number casts node to float64, +// including V_NUMBER|V_TRUE|V_FALSE|V_ANY|V_STRING|V_NULL, +// V_NONE it will return error +func (self *Node) Number() (json.Number, error) { + if err := self.checkRaw(); err != nil { + return json.Number(""), err + } + switch self.t { + case _V_NUMBER : return self.toNumber(), nil + case types.V_STRING : + if _, err := self.toInt64(); err == nil { + return self.toNumber(), nil + } else if _, err := self.toFloat64(); err == nil { + return self.toNumber(), nil + } else { + return json.Number(""), err + } + case types.V_TRUE : return json.Number("1"), nil + case types.V_FALSE : return json.Number("0"), nil + case types.V_NULL : return json.Number("0"), nil + case _V_ANY : + any := self.packAny() + switch v := any.(type) { + case bool : return castNumber(v), nil + case int : return castNumber(v != 0), nil + case int8 : return castNumber(v != 0), nil + case int16 : return castNumber(v != 0), nil + case int32 : return castNumber(v != 0), nil + case int64 : return castNumber(v != 0), nil + case uint : return castNumber(v != 0), nil + case uint8 : return castNumber(v != 0), nil + case uint16 : return castNumber(v != 0), nil + case uint32 : return castNumber(v != 0), nil + case uint64 : return castNumber(v != 0), nil + case float32: return castNumber(v != 0), nil + case float64: return castNumber(v != 0), nil + case string : + if _, err := strconv.ParseFloat(v, 64); err == nil { + return json.Number(v), nil + } else { + return json.Number(""), err + } + case json.Number: return v, nil + default: return json.Number(""), ErrUnsupportType + } + default : return json.Number(""), ErrUnsupportType + } +} + +// Number exports underlying float64 value, including V_NUMBER, V_ANY of json.Number +func (self *Node) StrictNumber() (json.Number, error) { + if err := self.checkRaw(); err != nil { + return json.Number(""), err + } + switch self.t { + case _V_NUMBER : return self.toNumber() , nil + case _V_ANY : + if v, ok := self.packAny().(json.Number); ok { + return v, nil + } else { + return json.Number(""), ErrUnsupportType + } + default : return json.Number(""), ErrUnsupportType + } +} + +// String cast node to string, +// including V_NUMBER|V_TRUE|V_FALSE|V_ANY|V_STRING|V_NULL, +// V_NONE it will return error +func (self *Node) String() (string, error) { + if err := self.checkRaw(); err != nil { + return "", err + } + switch self.t { + case types.V_NULL : return "" , nil + case types.V_TRUE : return "true" , nil + case types.V_FALSE : return "false", nil + case types.V_STRING, _V_NUMBER : return self.toString(), nil + case _V_ANY : + any := self.packAny() + switch v := any.(type) { + case bool : return strconv.FormatBool(v), nil + case int : return strconv.Itoa(v), nil + case int8 : return strconv.Itoa(int(v)), nil + case int16 : return strconv.Itoa(int(v)), nil + case int32 : return strconv.Itoa(int(v)), nil + case int64 : return strconv.Itoa(int(v)), nil + case uint : return strconv.Itoa(int(v)), nil + case uint8 : return strconv.Itoa(int(v)), nil + case uint16 : return strconv.Itoa(int(v)), nil + case uint32 : return strconv.Itoa(int(v)), nil + case uint64 : return strconv.Itoa(int(v)), nil + case float32: return strconv.FormatFloat(float64(v), 'g', -1, 64), nil + case float64: return strconv.FormatFloat(float64(v), 'g', -1, 64), nil + case string : return v, nil + case json.Number: return v.String(), nil + default: return "", ErrUnsupportType + } + default : return "" , ErrUnsupportType + } +} + +// StrictString returns string value (unescaped), including V_STRING, V_ANY of string. +// In other cases, it will return empty string. +func (self *Node) StrictString() (string, error) { + if err := self.checkRaw(); err != nil { + return "", err + } + switch self.t { + case types.V_STRING : return self.toString(), nil + case _V_ANY : + if v, ok := self.packAny().(string); ok { + return v, nil + } else { + return "", ErrUnsupportType + } + default : return "", ErrUnsupportType + } +} + +// Float64 cast node to float64, +// including V_NUMBER|V_TRUE|V_FALSE|V_ANY|V_STRING|V_NULL, +// V_NONE it will return error +func (self *Node) Float64() (float64, error) { + if err := self.checkRaw(); err != nil { + return 0.0, err + } + switch self.t { + case _V_NUMBER, types.V_STRING : return self.toFloat64() + case types.V_TRUE : return 1.0, nil + case types.V_FALSE : return 0.0, nil + case types.V_NULL : return 0.0, nil + case _V_ANY : + any := self.packAny() + switch v := any.(type) { + case bool : + if v { + return 1.0, nil + } else { + return 0.0, nil + } + case int : return float64(v), nil + case int8 : return float64(v), nil + case int16 : return float64(v), nil + case int32 : return float64(v), nil + case int64 : return float64(v), nil + case uint : return float64(v), nil + case uint8 : return float64(v), nil + case uint16 : return float64(v), nil + case uint32 : return float64(v), nil + case uint64 : return float64(v), nil + case float32: return float64(v), nil + case float64: return float64(v), nil + case string : + if f, err := strconv.ParseFloat(v, 64); err == nil { + return float64(f), nil + } else { + return 0, err + } + case json.Number: + if f, err := v.Float64(); err == nil { + return float64(f), nil + } else { + return 0, err + } + default : return 0, ErrUnsupportType + } + default : return 0.0, ErrUnsupportType + } +} + +// Float64 exports underlying float64 value, including V_NUMBER, V_ANY +func (self *Node) StrictFloat64() (float64, error) { + if err := self.checkRaw(); err != nil { + return 0.0, err + } + switch self.t { + case _V_NUMBER : return self.toFloat64() + case _V_ANY : + any := self.packAny() + switch v := any.(type) { + case float32 : return float64(v), nil + case float64 : return float64(v), nil + default : return 0, ErrUnsupportType + } + default : return 0.0, ErrUnsupportType + } +} + +/** Sequential Value Methods **/ + +// Len returns children count of a array|object|string node +// WARN: For partially loaded node, it also works but only counts the parsed children +func (self *Node) Len() (int, error) { + if err := self.checkRaw(); err != nil { + return 0, err + } + if self.t == types.V_ARRAY || self.t == types.V_OBJECT || self.t == _V_ARRAY_LAZY || self.t == _V_OBJECT_LAZY || self.t == types.V_STRING { + return int(self.l), nil + } else if self.t == _V_NONE || self.t == types.V_NULL { + return 0, nil + } else { + return 0, ErrUnsupportType + } +} + +func (self *Node) len() int { + return int(self.l) +} + +// Cap returns malloc capacity of a array|object node for children +func (self *Node) Cap() (int, error) { + if err := self.checkRaw(); err != nil { + return 0, err + } + switch self.t { + case types.V_ARRAY: return (*linkedNodes)(self.p).Cap(), nil + case types.V_OBJECT: return (*linkedPairs)(self.p).Cap(), nil + case _V_ARRAY_LAZY: return (*parseArrayStack)(self.p).v.Cap(), nil + case _V_OBJECT_LAZY: return (*parseObjectStack)(self.p).v.Cap(), nil + case _V_NONE, types.V_NULL: return 0, nil + default: return 0, ErrUnsupportType + } +} + +// Set sets the node of given key under self, and reports if the key has existed. +// +// If self is V_NONE or V_NULL, it becomes V_OBJECT and sets the node at the key. +func (self *Node) Set(key string, node Node) (bool, error) { + if err := self.checkRaw(); err != nil { + return false, err + } + if err := node.Check(); err != nil { + return false, err + } + + if self.t == _V_NONE || self.t == types.V_NULL { + *self = NewObject([]Pair{NewPair(key, node)}) + return false, nil + } else if self.itype() != types.V_OBJECT { + return false, ErrUnsupportType + } + + p := self.Get(key) + + if !p.Exists() { + // self must be fully-loaded here + if self.len() == 0 { + *self = newObject(new(linkedPairs)) + } + s := (*linkedPairs)(self.p) + s.Push(NewPair(key, node)) + self.l++ + return false, nil + + } else if err := p.Check(); err != nil { + return false, err + } + + *p = node + return true, nil +} + +// SetAny wraps val with V_ANY node, and Set() the node. +func (self *Node) SetAny(key string, val interface{}) (bool, error) { + return self.Set(key, NewAny(val)) +} + +// Unset REMOVE (soft) the node of given key under object parent, and reports if the key has existed. +func (self *Node) Unset(key string) (bool, error) { + if err := self.should(types.V_OBJECT); err != nil { + return false, err + } + // NOTICE: must get accurate length before deduct + if err := self.skipAllKey(); err != nil { + return false, err + } + p, i := self.skipKey(key) + if !p.Exists() { + return false, nil + } else if err := p.Check(); err != nil { + return false, err + } + self.removePairAt(i) + return true, nil +} + +// SetByIndex sets the node of given index, and reports if the key has existed. +// +// The index must be within self's children. +func (self *Node) SetByIndex(index int, node Node) (bool, error) { + if err := self.checkRaw(); err != nil { + return false, err + } + if err := node.Check(); err != nil { + return false, err + } + + if index == 0 && (self.t == _V_NONE || self.t == types.V_NULL) { + *self = NewArray([]Node{node}) + return false, nil + } + + p := self.Index(index) + if !p.Exists() { + return false, ErrNotExist + } else if err := p.Check(); err != nil { + return false, err + } + + *p = node + return true, nil +} + +// SetAny wraps val with V_ANY node, and SetByIndex() the node. +func (self *Node) SetAnyByIndex(index int, val interface{}) (bool, error) { + return self.SetByIndex(index, NewAny(val)) +} + +// UnsetByIndex REMOVE (softly) the node of given index. +// +// WARN: this will change address of elements, which is a dangerous action. +// Use Unset() for object or Pop() for array instead. +func (self *Node) UnsetByIndex(index int) (bool, error) { + if err := self.checkRaw(); err != nil { + return false, err + } + + var p *Node + it := self.itype() + + if it == types.V_ARRAY { + if err := self.skipAllIndex(); err != nil { + return false, err + } + p = self.nodeAt(index) + } else if it == types.V_OBJECT { + if err := self.skipAllKey(); err != nil { + return false, err + } + pr := self.pairAt(index) + if pr == nil { + return false, ErrNotExist + } + p = &pr.Value + } else { + return false, ErrUnsupportType + } + + if !p.Exists() { + return false, ErrNotExist + } + + // last elem + if index == self.len() - 1 { + return true, self.Pop() + } + + // not last elem, self.len() change but linked-chunk not change + if it == types.V_ARRAY { + self.removeNode(index) + }else if it == types.V_OBJECT { + self.removePair(index) + } + return true, nil +} + +// Add appends the given node under self. +// +// If self is V_NONE or V_NULL, it becomes V_ARRAY and sets the node at index 0. +func (self *Node) Add(node Node) error { + if err := self.checkRaw(); err != nil { + return err + } + + if self != nil && (self.t == _V_NONE || self.t == types.V_NULL) { + *self = NewArray([]Node{node}) + return nil + } + if err := self.should(types.V_ARRAY); err != nil { + return err + } + + s, err := self.unsafeArray() + if err != nil { + return err + } + + // Notice: array won't have unset node in tail + s.Push(node) + self.l++ + return nil +} + +// Pop remove the last child of the V_Array or V_Object node. +func (self *Node) Pop() error { + if err := self.checkRaw(); err != nil { + return err + } + + if it := self.itype(); it == types.V_ARRAY { + s, err := self.unsafeArray() + if err != nil { + return err + } + // remove tail unset nodes + for i := s.Len()-1; i >= 0; i-- { + if s.At(i).Exists() { + s.Pop() + self.l-- + break + } + s.Pop() + } + + } else if it == types.V_OBJECT { + s, err := self.unsafeMap() + if err != nil { + return err + } + // remove tail unset nodes + for i := s.Len()-1; i >= 0; i-- { + if p := s.At(i); p != nil && p.Value.Exists() { + s.Pop() + self.l-- + break + } + s.Pop() + } + + } else { + return ErrUnsupportType + } + + return nil +} + +// Move moves the child at src index to dst index, +// meanwhile slides sliblings from src+1 to dst. +// +// WARN: this will change address of elements, which is a dangerous action. +func (self *Node) Move(dst, src int) error { + if err := self.should(types.V_ARRAY); err != nil { + return err + } + + s, err := self.unsafeArray() + if err != nil { + return err + } + + // check if any unset node exists + if l := s.Len(); self.len() != l { + di, si := dst, src + // find real pos of src and dst + for i := 0; i < l; i++ { + if s.At(i).Exists() { + di-- + si-- + } + if di == -1 { + dst = i + di-- + } + if si == -1 { + src = i + si-- + } + if di == -2 && si == -2 { + break + } + } + } + + s.MoveOne(src, dst) + return nil +} + +// SetAny wraps val with V_ANY node, and Add() the node. +func (self *Node) AddAny(val interface{}) error { + return self.Add(NewAny(val)) +} + +// GetByPath load given path on demands, +// which only ensure nodes before this path got parsed. +// +// Note, the api expects the json is well-formed at least, +// otherwise it may return unexpected result. +func (self *Node) GetByPath(path ...interface{}) *Node { + if !self.Valid() { + return self + } + var s = self + for _, p := range path { + switch p := p.(type) { + case int: + s = s.Index(p) + if !s.Valid() { + return s + } + case string: + s = s.Get(p) + if !s.Valid() { + return s + } + default: + panic("path must be either int or string") + } + } + return s +} + +// Get loads given key of an object node on demands +func (self *Node) Get(key string) *Node { + if err := self.should(types.V_OBJECT); err != nil { + return unwrapError(err) + } + n, _ := self.skipKey(key) + return n +} + +// Index indexies node at given idx, +// node type CAN be either V_OBJECT or V_ARRAY +func (self *Node) Index(idx int) *Node { + if err := self.checkRaw(); err != nil { + return unwrapError(err) + } + + it := self.itype() + if it == types.V_ARRAY { + return self.skipIndex(idx) + + }else if it == types.V_OBJECT { + pr := self.skipIndexPair(idx) + if pr == nil { + return newError(_ERR_NOT_FOUND, "value not exists") + } + return &pr.Value + + } else { + return newError(_ERR_UNSUPPORT_TYPE, fmt.Sprintf("unsupported type: %v", self.itype())) + } +} + +// IndexPair indexies pair at given idx, +// node type MUST be either V_OBJECT +func (self *Node) IndexPair(idx int) *Pair { + if err := self.should(types.V_OBJECT); err != nil { + return nil + } + return self.skipIndexPair(idx) +} + +func (self *Node) indexOrGet(idx int, key string) (*Node, int) { + if err := self.should(types.V_OBJECT); err != nil { + return unwrapError(err), idx + } + + pr := self.skipIndexPair(idx) + if pr != nil && pr.Key == key { + return &pr.Value, idx + } + + return self.skipKey(key) +} + +// IndexOrGet firstly use idx to index a value and check if its key matches +// If not, then use the key to search value +func (self *Node) IndexOrGet(idx int, key string) *Node { + node, _ := self.indexOrGet(idx, key) + return node +} + +// IndexOrGetWithIdx attempts to retrieve a node by index and key, returning the node and its correct index. +// If the key does not match at the given index, it searches by key and returns the node with its updated index. +func (self *Node) IndexOrGetWithIdx(idx int, key string) (*Node, int) { + return self.indexOrGet(idx, key) +} + +/** Generic Value Converters **/ + +// Map loads all keys of an object node +func (self *Node) Map() (map[string]interface{}, error) { + if self.isAny() { + any := self.packAny() + if v, ok := any.(map[string]interface{}); ok { + return v, nil + } else { + return nil, ErrUnsupportType + } + } + if err := self.should(types.V_OBJECT); err != nil { + return nil, err + } + if err := self.loadAllKey(false); err != nil { + return nil, err + } + return self.toGenericObject() +} + +// MapUseNumber loads all keys of an object node, with numeric nodes casted to json.Number +func (self *Node) MapUseNumber() (map[string]interface{}, error) { + if self.isAny() { + any := self.packAny() + if v, ok := any.(map[string]interface{}); ok { + return v, nil + } else { + return nil, ErrUnsupportType + } + } + if err := self.should(types.V_OBJECT); err != nil { + return nil, err + } + if err := self.loadAllKey(false); err != nil { + return nil, err + } + return self.toGenericObjectUseNumber() +} + +// MapUseNode scans both parsed and non-parsed children nodes, +// and map them by their keys +func (self *Node) MapUseNode() (map[string]Node, error) { + if self.isAny() { + any := self.packAny() + if v, ok := any.(map[string]Node); ok { + return v, nil + } else { + return nil, ErrUnsupportType + } + } + if err := self.should(types.V_OBJECT); err != nil { + return nil, err + } + if err := self.skipAllKey(); err != nil { + return nil, err + } + return self.toGenericObjectUseNode() +} + +// MapUnsafe exports the underlying pointer to its children map +// WARN: don't use it unless you know what you are doing +// +// Deprecated: this API now returns copied nodes instead of directly reference, +// func (self *Node) UnsafeMap() ([]Pair, error) { +// if err := self.should(types.V_OBJECT, "an object"); err != nil { +// return nil, err +// } +// if err := self.skipAllKey(); err != nil { +// return nil, err +// } +// return self.toGenericObjectUsePair() +// } + +//go:nocheckptr +func (self *Node) unsafeMap() (*linkedPairs, error) { + if err := self.skipAllKey(); err != nil { + return nil, err + } + if self.p == nil { + *self = newObject(new(linkedPairs)) + } + return (*linkedPairs)(self.p), nil +} + +// SortKeys sorts children of a V_OBJECT node in ascending key-order. +// If recurse is true, it recursively sorts children's children as long as a V_OBJECT node is found. +func (self *Node) SortKeys(recurse bool) error { + // check raw node first + if err := self.checkRaw(); err != nil { + return err + } + if self.itype() == types.V_OBJECT { + return self.sortKeys(recurse) + } else if self.itype() == types.V_ARRAY { + var err error + err2 := self.ForEach(func(path Sequence, node *Node) bool { + it := node.itype() + if it == types.V_ARRAY || it == types.V_OBJECT { + err = node.SortKeys(recurse) + if err != nil { + return false + } + } + return true + }) + if err != nil { + return err + } + return err2 + } else { + return nil + } +} + +func (self *Node) sortKeys(recurse bool) (err error) { + // check raw node first + if err := self.checkRaw(); err != nil { + return err + } + ps, err := self.unsafeMap() + if err != nil { + return err + } + ps.Sort() + if recurse { + var sc Scanner + sc = func(path Sequence, node *Node) bool { + if node.itype() == types.V_OBJECT { + if err := node.sortKeys(recurse); err != nil { + return false + } + } + if node.itype() == types.V_ARRAY { + if err := node.ForEach(sc); err != nil { + return false + } + } + return true + } + if err := self.ForEach(sc); err != nil { + return err + } + } + return nil +} + +// Array loads all indexes of an array node +func (self *Node) Array() ([]interface{}, error) { + if self.isAny() { + any := self.packAny() + if v, ok := any.([]interface{}); ok { + return v, nil + } else { + return nil, ErrUnsupportType + } + } + if err := self.should(types.V_ARRAY); err != nil { + return nil, err + } + if err := self.loadAllIndex(false); err != nil { + return nil, err + } + return self.toGenericArray() +} + +// ArrayUseNumber loads all indexes of an array node, with numeric nodes casted to json.Number +func (self *Node) ArrayUseNumber() ([]interface{}, error) { + if self.isAny() { + any := self.packAny() + if v, ok := any.([]interface{}); ok { + return v, nil + } else { + return nil, ErrUnsupportType + } + } + if err := self.should(types.V_ARRAY); err != nil { + return nil, err + } + if err := self.loadAllIndex(false); err != nil { + return nil, err + } + return self.toGenericArrayUseNumber() +} + +// ArrayUseNode copies both parsed and non-parsed children nodes, +// and indexes them by original order +func (self *Node) ArrayUseNode() ([]Node, error) { + if self.isAny() { + any := self.packAny() + if v, ok := any.([]Node); ok { + return v, nil + } else { + return nil, ErrUnsupportType + } + } + if err := self.should(types.V_ARRAY); err != nil { + return nil, err + } + if err := self.skipAllIndex(); err != nil { + return nil, err + } + return self.toGenericArrayUseNode() +} + +// ArrayUnsafe exports the underlying pointer to its children array +// WARN: don't use it unless you know what you are doing +// +// Deprecated: this API now returns copied nodes instead of directly reference, +// which has no difference with ArrayUseNode +// func (self *Node) UnsafeArray() ([]Node, error) { +// if err := self.should(types.V_ARRAY, "an array"); err != nil { +// return nil, err +// } +// if err := self.skipAllIndex(); err != nil { +// return nil, err +// } +// return self.toGenericArrayUseNode() +// } + +func (self *Node) unsafeArray() (*linkedNodes, error) { + if err := self.skipAllIndex(); err != nil { + return nil, err + } + if self.p == nil { + *self = newArray(new(linkedNodes)) + } + return (*linkedNodes)(self.p), nil +} + +// Interface loads all children under all paths from this node, +// and converts itself as generic type. +// WARN: all numeric nodes are casted to float64 +func (self *Node) Interface() (interface{}, error) { + if err := self.checkRaw(); err != nil { + return nil, err + } + switch self.t { + case V_ERROR : return nil, self.Check() + case types.V_NULL : return nil, nil + case types.V_TRUE : return true, nil + case types.V_FALSE : return false, nil + case types.V_ARRAY : return self.toGenericArray() + case types.V_OBJECT : return self.toGenericObject() + case types.V_STRING : return self.toString(), nil + case _V_NUMBER : + v, err := self.toFloat64() + if err != nil { + return nil, err + } + return v, nil + case _V_ARRAY_LAZY : + if err := self.loadAllIndex(false); err != nil { + return nil, err + } + return self.toGenericArray() + case _V_OBJECT_LAZY : + if err := self.loadAllKey(false); err != nil { + return nil, err + } + return self.toGenericObject() + case _V_ANY: + switch v := self.packAny().(type) { + case Node : return v.Interface() + case *Node: return v.Interface() + default : return v, nil + } + default : return nil, ErrUnsupportType + } +} + +func (self *Node) packAny() interface{} { + return *(*interface{})(self.p) +} + +// InterfaceUseNumber works same with Interface() +// except numeric nodes are casted to json.Number +func (self *Node) InterfaceUseNumber() (interface{}, error) { + if err := self.checkRaw(); err != nil { + return nil, err + } + switch self.t { + case V_ERROR : return nil, self.Check() + case types.V_NULL : return nil, nil + case types.V_TRUE : return true, nil + case types.V_FALSE : return false, nil + case types.V_ARRAY : return self.toGenericArrayUseNumber() + case types.V_OBJECT : return self.toGenericObjectUseNumber() + case types.V_STRING : return self.toString(), nil + case _V_NUMBER : return self.toNumber(), nil + case _V_ARRAY_LAZY : + if err := self.loadAllIndex(false); err != nil { + return nil, err + } + return self.toGenericArrayUseNumber() + case _V_OBJECT_LAZY : + if err := self.loadAllKey(false); err != nil { + return nil, err + } + return self.toGenericObjectUseNumber() + case _V_ANY : return self.packAny(), nil + default : return nil, ErrUnsupportType + } +} + +// InterfaceUseNode clone itself as a new node, +// or its children as map[string]Node (or []Node) +func (self *Node) InterfaceUseNode() (interface{}, error) { + if err := self.checkRaw(); err != nil { + return nil, err + } + switch self.t { + case types.V_ARRAY : return self.toGenericArrayUseNode() + case types.V_OBJECT : return self.toGenericObjectUseNode() + case _V_ARRAY_LAZY : + if err := self.skipAllIndex(); err != nil { + return nil, err + } + return self.toGenericArrayUseNode() + case _V_OBJECT_LAZY : + if err := self.skipAllKey(); err != nil { + return nil, err + } + return self.toGenericObjectUseNode() + default : return *self, self.Check() + } +} + +// LoadAll loads the node's children +// and ensure all its children can be READ concurrently (include its children's children) +func (self *Node) LoadAll() error { + return self.Load() +} + +// Load loads the node's children as parsed. +// and ensure all its children can be READ concurrently (include its children's children) +func (self *Node) Load() error { + switch self.t { + case _V_ARRAY_LAZY: self.loadAllIndex(true) + case _V_OBJECT_LAZY: self.loadAllKey(true) + case V_ERROR: return self + case V_NONE: return nil + } + if self.m == nil { + self.m = new(sync.RWMutex) + } + return self.checkRaw() +} + +/**---------------------------------- Internal Helper Methods ----------------------------------**/ + +func (self *Node) should(t types.ValueType) error { + if err := self.checkRaw(); err != nil { + return err + } + if self.itype() != t { + return ErrUnsupportType + } + return nil +} + +func (self *Node) nodeAt(i int) *Node { + var p *linkedNodes + if self.isLazy() { + _, stack := self.getParserAndArrayStack() + p = &stack.v + } else { + p = (*linkedNodes)(self.p) + if l := p.Len(); l != self.len() { + // some nodes got unset, iterate to skip them + for j:=0; j 0 { + /* linear search */ + var p *Pair + var i int + if lazy { + s := (*parseObjectStack)(self.p) + p, i = s.v.Get(key) + } else { + p, i = (*linkedPairs)(self.p).Get(key) + } + + if p != nil { + return &p.Value, i + } + } + + /* not found */ + if !lazy { + return nil, -1 + } + + // lazy load + for last, i := self.skipNextPair(), nb; last != nil; last, i = self.skipNextPair(), i+1 { + if last.Value.Check() != nil { + return &last.Value, -1 + } + if last.Key == key { + return &last.Value, i + } + } + + return nil, -1 +} + +func (self *Node) skipIndex(index int) *Node { + nb := self.len() + if nb > index { + v := self.nodeAt(index) + return v + } + if !self.isLazy() { + return nil + } + + // lazy load + for last := self.skipNextNode(); last != nil; last = self.skipNextNode(){ + if last.Check() != nil { + return last + } + if self.len() > index { + return last + } + } + + return nil +} + +func (self *Node) skipIndexPair(index int) *Pair { + nb := self.len() + if nb > index { + return self.pairAt(index) + } + if !self.isLazy() { + return nil + } + + // lazy load + for last := self.skipNextPair(); last != nil; last = self.skipNextPair(){ + if last.Value.Check() != nil { + return last + } + if self.len() > index { + return last + } + } + + return nil +} + +func (self *Node) loadAllIndex(loadOnce bool) error { + if !self.isLazy() { + return nil + } + var err types.ParsingError + parser, stack := self.getParserAndArrayStack() + if !loadOnce { + parser.noLazy = true + } else { + parser.loadOnce = true + } + *self, err = parser.decodeArray(&stack.v) + if err != 0 { + return parser.ExportError(err) + } + return nil +} + +func (self *Node) loadAllKey(loadOnce bool) error { + if !self.isLazy() { + return nil + } + var err types.ParsingError + parser, stack := self.getParserAndObjectStack() + if !loadOnce { + parser.noLazy = true + *self, err = parser.decodeObject(&stack.v) + } else { + parser.loadOnce = true + *self, err = parser.decodeObject(&stack.v) + } + if err != 0 { + return parser.ExportError(err) + } + return nil +} + +func (self *Node) removeNode(i int) { + node := self.nodeAt(i) + if node == nil { + return + } + *node = Node{} + // NOTICE: not be consistent with linkedNode.Len() + self.l-- +} + +func (self *Node) removePair(i int) { + last := self.pairAt(i) + if last == nil { + return + } + *last = Pair{} + // NOTICE: should be consistent with linkedPair.Len() + self.l-- +} + +func (self *Node) removePairAt(i int) { + p := (*linkedPairs)(self.p).At(i) + if p == nil { + return + } + *p = Pair{} + // NOTICE: should be consistent with linkedPair.Len() + self.l-- +} + +func (self *Node) toGenericArray() ([]interface{}, error) { + nb := self.len() + if nb == 0 { + return []interface{}{}, nil + } + ret := make([]interface{}, 0, nb) + + /* convert each item */ + it := self.values() + for v := it.next(); v != nil; v = it.next() { + vv, err := v.Interface() + if err != nil { + return nil, err + } + ret = append(ret, vv) + } + + /* all done */ + return ret, nil +} + +func (self *Node) toGenericArrayUseNumber() ([]interface{}, error) { + nb := self.len() + if nb == 0 { + return []interface{}{}, nil + } + ret := make([]interface{}, 0, nb) + + /* convert each item */ + it := self.values() + for v := it.next(); v != nil; v = it.next() { + vv, err := v.InterfaceUseNumber() + if err != nil { + return nil, err + } + ret = append(ret, vv) + } + + /* all done */ + return ret, nil +} + +func (self *Node) toGenericArrayUseNode() ([]Node, error) { + var nb = self.len() + if nb == 0 { + return []Node{}, nil + } + + var s = (*linkedNodes)(self.p) + var out = make([]Node, nb) + s.ToSlice(out) + + return out, nil +} + +func (self *Node) toGenericObject() (map[string]interface{}, error) { + nb := self.len() + if nb == 0 { + return map[string]interface{}{}, nil + } + ret := make(map[string]interface{}, nb) + + /* convert each item */ + it := self.properties() + for v := it.next(); v != nil; v = it.next() { + vv, err := v.Value.Interface() + if err != nil { + return nil, err + } + ret[v.Key] = vv + } + + /* all done */ + return ret, nil +} + + +func (self *Node) toGenericObjectUseNumber() (map[string]interface{}, error) { + nb := self.len() + if nb == 0 { + return map[string]interface{}{}, nil + } + ret := make(map[string]interface{}, nb) + + /* convert each item */ + it := self.properties() + for v := it.next(); v != nil; v = it.next() { + vv, err := v.Value.InterfaceUseNumber() + if err != nil { + return nil, err + } + ret[v.Key] = vv + } + + /* all done */ + return ret, nil +} + +func (self *Node) toGenericObjectUseNode() (map[string]Node, error) { + var nb = self.len() + if nb == 0 { + return map[string]Node{}, nil + } + + var s = (*linkedPairs)(self.p) + var out = make(map[string]Node, nb) + s.ToMap(out) + + /* all done */ + return out, nil +} + +/**------------------------------------ Factory Methods ------------------------------------**/ + +var ( + nullNode = Node{t: types.V_NULL} + trueNode = Node{t: types.V_TRUE} + falseNode = Node{t: types.V_FALSE} +) + +// NewRaw creates a node of raw json. +// If the input json is invalid, NewRaw returns a error Node. +func NewRaw(json string) Node { + parser := NewParserObj(json) + start, err := parser.skip() + if err != 0 { + return *newError(err, err.Message()) + } + it := switchRawType(parser.s[start]) + if it == _V_NONE { + return Node{} + } + return newRawNode(parser.s[start:parser.p], it, false) +} + +// NewRawConcurrentRead creates a node of raw json, which can be READ +// (GetByPath/Get/Index/GetOrIndex/Int64/Bool/Float64/String/Number/Interface/Array/Map/Raw/MarshalJSON) concurrently. +// If the input json is invalid, NewRaw returns a error Node. +func NewRawConcurrentRead(json string) Node { + parser := NewParserObj(json) + start, err := parser.skip() + if err != 0 { + return *newError(err, err.Message()) + } + it := switchRawType(parser.s[start]) + if it == _V_NONE { + return Node{} + } + return newRawNode(parser.s[start:parser.p], it, true) +} + +// NewAny creates a node of type V_ANY if any's type isn't Node or *Node, +// which stores interface{} and can be only used for `.Interface()`\`.MarshalJSON()`. +func NewAny(any interface{}) Node { + switch n := any.(type) { + case Node: + return n + case *Node: + return *n + default: + return Node{ + t: _V_ANY, + p: unsafe.Pointer(&any), + } + } +} + +// NewBytes encodes given src with Base64 (RFC 4648), and creates a node of type V_STRING. +func NewBytes(src []byte) Node { + if len(src) == 0 { + panic("empty src bytes") + } + out := rt.EncodeBase64ToString(src) + return NewString(out) +} + +// NewNull creates a node of type V_NULL +func NewNull() Node { + return Node{ + p: nil, + t: types.V_NULL, + } +} + +// NewBool creates a node of type bool: +// If v is true, returns V_TRUE node +// If v is false, returns V_FALSE node +func NewBool(v bool) Node { + var t = types.V_FALSE + if v { + t = types.V_TRUE + } + return Node{ + p: nil, + t: t, + } +} + +// NewNumber creates a json.Number node +// v must be a decimal string complying with RFC8259 +func NewNumber(v string) Node { + return Node{ + l: uint(len(v)), + p: rt.StrPtr(v), + t: _V_NUMBER, + } +} + +func (node *Node) toNumber() json.Number { + return json.Number(rt.StrFrom(node.p, int64(node.l))) +} + +func (self *Node) toString() string { + return rt.StrFrom(self.p, int64(self.l)) +} + +func (node *Node) toFloat64() (float64, error) { + ret, err := node.toNumber().Float64() + if err != nil { + return 0, err + } + return ret, nil +} + +func (node *Node) toInt64() (int64, error) { + ret,err := node.toNumber().Int64() + if err != nil { + return 0, err + } + return ret, nil +} + +func newBytes(v []byte) Node { + return Node{ + t: types.V_STRING, + p: mem2ptr(v), + l: uint(len(v)), + } +} + +// NewString creates a node of type V_STRING. +// v is considered to be a valid UTF-8 string, +// which means it won't be validated and unescaped. +// when the node is encoded to json, v will be escaped. +func NewString(v string) Node { + return Node{ + t: types.V_STRING, + p: rt.StrPtr(v), + l: uint(len(v)), + } +} + +// NewArray creates a node of type V_ARRAY, +// using v as its underlying children +func NewArray(v []Node) Node { + s := new(linkedNodes) + s.FromSlice(v) + return newArray(s) +} + +const _Threshold_Index = 16 + +func newArray(v *linkedNodes) Node { + return Node{ + t: types.V_ARRAY, + l: uint(v.Len()), + p: unsafe.Pointer(v), + } +} + +func (self *Node) setArray(v *linkedNodes) { + self.t = types.V_ARRAY + self.l = uint(v.Len()) + self.p = unsafe.Pointer(v) +} + +// NewObject creates a node of type V_OBJECT, +// using v as its underlying children +func NewObject(v []Pair) Node { + s := new(linkedPairs) + s.FromSlice(v) + return newObject(s) +} + +func newObject(v *linkedPairs) Node { + if v.size > _Threshold_Index { + v.BuildIndex() + } + return Node{ + t: types.V_OBJECT, + l: uint(v.Len()), + p: unsafe.Pointer(v), + } +} + +func (self *Node) setObject(v *linkedPairs) { + if v.size > _Threshold_Index { + v.BuildIndex() + } + self.t = types.V_OBJECT + self.l = uint(v.Len()) + self.p = unsafe.Pointer(v) +} + +func (self *Node) parseRaw(full bool) { + lock := self.lock() + defer self.unlock() + if !self.isRaw() { + return + } + raw := self.toString() + parser := NewParserObj(raw) + var e types.ParsingError + if full { + parser.noLazy = true + *self, e = parser.Parse() + } else if lock { + var n Node + parser.noLazy = true + parser.loadOnce = true + n, e = parser.Parse() + self.assign(n) + } else { + *self, e = parser.Parse() + } + if e != 0 { + *self = *newSyntaxError(parser.syntaxError(e)) + } +} + +func (self *Node) assign(n Node) { + self.l = n.l + self.p = n.p + atomic.StoreInt64(&self.t, n.t) +} diff --git a/vendor/github.com/bytedance/sonic/ast/parser.go b/vendor/github.com/bytedance/sonic/ast/parser.go new file mode 100644 index 00000000..30bd1f45 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/ast/parser.go @@ -0,0 +1,766 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ast + +import ( + "fmt" + "sync" + "sync/atomic" + + "github.com/bytedance/sonic/internal/native/types" + "github.com/bytedance/sonic/internal/rt" +) + +const ( + _DEFAULT_NODE_CAP int = 16 + _APPEND_GROW_SHIFT = 1 +) + +const ( + _ERR_NOT_FOUND types.ParsingError = 33 + _ERR_UNSUPPORT_TYPE types.ParsingError = 34 +) + +var ( + // ErrNotExist means both key and value doesn't exist + ErrNotExist error = newError(_ERR_NOT_FOUND, "value not exists") + + // ErrUnsupportType means API on the node is unsupported + ErrUnsupportType error = newError(_ERR_UNSUPPORT_TYPE, "unsupported type") +) + +type Parser struct { + p int + s string + noLazy bool + loadOnce bool + skipValue bool + dbuf *byte +} + +/** Parser Private Methods **/ + +func (self *Parser) delim() types.ParsingError { + n := len(self.s) + p := self.lspace(self.p) + + /* check for EOF */ + if p >= n { + return types.ERR_EOF + } + + /* check for the delimtier */ + if self.s[p] != ':' { + return types.ERR_INVALID_CHAR + } + + /* update the read pointer */ + self.p = p + 1 + return 0 +} + +func (self *Parser) object() types.ParsingError { + n := len(self.s) + p := self.lspace(self.p) + + /* check for EOF */ + if p >= n { + return types.ERR_EOF + } + + /* check for the delimtier */ + if self.s[p] != '{' { + return types.ERR_INVALID_CHAR + } + + /* update the read pointer */ + self.p = p + 1 + return 0 +} + +func (self *Parser) array() types.ParsingError { + n := len(self.s) + p := self.lspace(self.p) + + /* check for EOF */ + if p >= n { + return types.ERR_EOF + } + + /* check for the delimtier */ + if self.s[p] != '[' { + return types.ERR_INVALID_CHAR + } + + /* update the read pointer */ + self.p = p + 1 + return 0 +} + +func (self *Parser) lspace(sp int) int { + ns := len(self.s) + for ; sp= 0 && isSpace(self.s[self.p]); self.p-=1 {} +} + +func (self *Parser) decodeArray(ret *linkedNodes) (Node, types.ParsingError) { + sp := self.p + ns := len(self.s) + + /* check for EOF */ + if self.p = self.lspace(sp); self.p >= ns { + return Node{}, types.ERR_EOF + } + + /* check for empty array */ + if self.s[self.p] == ']' { + self.p++ + return Node{t: types.V_ARRAY}, 0 + } + + /* allocate array space and parse every element */ + for { + var val Node + var err types.ParsingError + + if self.skipValue { + /* skip the value */ + var start int + if start, err = self.skipFast(); err != 0 { + return Node{}, err + } + if self.p > ns { + return Node{}, types.ERR_EOF + } + t := switchRawType(self.s[start]) + if t == _V_NONE { + return Node{}, types.ERR_INVALID_CHAR + } + val = newRawNode(self.s[start:self.p], t, false) + }else{ + /* decode the value */ + if val, err = self.Parse(); err != 0 { + return Node{}, err + } + } + + /* add the value to result */ + ret.Push(val) + self.p = self.lspace(self.p) + + /* check for EOF */ + if self.p >= ns { + return Node{}, types.ERR_EOF + } + + /* check for the next character */ + switch self.s[self.p] { + case ',' : self.p++ + case ']' : self.p++; return newArray(ret), 0 + default: + // if val.isLazy() { + // return newLazyArray(self, ret), 0 + // } + return Node{}, types.ERR_INVALID_CHAR + } + } +} + +func (self *Parser) decodeObject(ret *linkedPairs) (Node, types.ParsingError) { + sp := self.p + ns := len(self.s) + + /* check for EOF */ + if self.p = self.lspace(sp); self.p >= ns { + return Node{}, types.ERR_EOF + } + + /* check for empty object */ + if self.s[self.p] == '}' { + self.p++ + return Node{t: types.V_OBJECT}, 0 + } + + /* decode each pair */ + for { + var val Node + var njs types.JsonState + var err types.ParsingError + + /* decode the key */ + if njs = self.decodeValue(); njs.Vt != types.V_STRING { + return Node{}, types.ERR_INVALID_CHAR + } + + /* extract the key */ + idx := self.p - 1 + key := self.s[njs.Iv:idx] + + /* check for escape sequence */ + if njs.Ep != -1 { + if key, err = unquote(key); err != 0 { + return Node{}, err + } + } + + /* expect a ':' delimiter */ + if err = self.delim(); err != 0 { + return Node{}, err + } + + + if self.skipValue { + /* skip the value */ + var start int + if start, err = self.skipFast(); err != 0 { + return Node{}, err + } + if self.p > ns { + return Node{}, types.ERR_EOF + } + t := switchRawType(self.s[start]) + if t == _V_NONE { + return Node{}, types.ERR_INVALID_CHAR + } + val = newRawNode(self.s[start:self.p], t, false) + } else { + /* decode the value */ + if val, err = self.Parse(); err != 0 { + return Node{}, err + } + } + + /* add the value to result */ + // FIXME: ret's address may change here, thus previous referred node in ret may be invalid !! + ret.Push(NewPair(key, val)) + self.p = self.lspace(self.p) + + /* check for EOF */ + if self.p >= ns { + return Node{}, types.ERR_EOF + } + + /* check for the next character */ + switch self.s[self.p] { + case ',' : self.p++ + case '}' : self.p++; return newObject(ret), 0 + default: + // if val.isLazy() { + // return newLazyObject(self, ret), 0 + // } + return Node{}, types.ERR_INVALID_CHAR + } + } +} + +func (self *Parser) decodeString(iv int64, ep int) (Node, types.ParsingError) { + p := self.p - 1 + s := self.s[iv:p] + + /* fast path: no escape sequence */ + if ep == -1 { + return NewString(s), 0 + } + + /* unquote the string */ + out, err := unquote(s) + + /* check for errors */ + if err != 0 { + return Node{}, err + } else { + return newBytes(rt.Str2Mem(out)), 0 + } +} + +/** Parser Interface **/ + +func (self *Parser) Pos() int { + return self.p +} + + +// Parse returns a ast.Node representing the parser's JSON. +// NOTICE: the specific parsing lazy dependens parser's option +// It only parse first layer and first child for Object or Array be default +func (self *Parser) Parse() (Node, types.ParsingError) { + switch val := self.decodeValue(); val.Vt { + case types.V_EOF : return Node{}, types.ERR_EOF + case types.V_NULL : return nullNode, 0 + case types.V_TRUE : return trueNode, 0 + case types.V_FALSE : return falseNode, 0 + case types.V_STRING : return self.decodeString(val.Iv, val.Ep) + case types.V_ARRAY: + s := self.p - 1; + if p := skipBlank(self.s, self.p); p >= self.p && self.s[p] == ']' { + self.p = p + 1 + return Node{t: types.V_ARRAY}, 0 + } + if self.noLazy { + if self.loadOnce { + self.noLazy = false + } + return self.decodeArray(new(linkedNodes)) + } + // NOTICE: loadOnce always keep raw json for object or array + if self.loadOnce { + self.p = s + s, e := self.skipFast() + if e != 0 { + return Node{}, e + } + return newRawNode(self.s[s:self.p], types.V_ARRAY, true), 0 + } + return newLazyArray(self), 0 + case types.V_OBJECT: + s := self.p - 1; + if p := skipBlank(self.s, self.p); p >= self.p && self.s[p] == '}' { + self.p = p + 1 + return Node{t: types.V_OBJECT}, 0 + } + // NOTICE: loadOnce always keep raw json for object or array + if self.noLazy { + if self.loadOnce { + self.noLazy = false + } + return self.decodeObject(new(linkedPairs)) + } + if self.loadOnce { + self.p = s + s, e := self.skipFast() + if e != 0 { + return Node{}, e + } + return newRawNode(self.s[s:self.p], types.V_OBJECT, true), 0 + } + return newLazyObject(self), 0 + case types.V_DOUBLE : return NewNumber(self.s[val.Ep:self.p]), 0 + case types.V_INTEGER : return NewNumber(self.s[val.Ep:self.p]), 0 + default : return Node{}, types.ParsingError(-val.Vt) + } +} + +func (self *Parser) searchKey(match string) types.ParsingError { + ns := len(self.s) + if err := self.object(); err != 0 { + return err + } + + /* check for EOF */ + if self.p = self.lspace(self.p); self.p >= ns { + return types.ERR_EOF + } + + /* check for empty object */ + if self.s[self.p] == '}' { + self.p++ + return _ERR_NOT_FOUND + } + + var njs types.JsonState + var err types.ParsingError + /* decode each pair */ + for { + + /* decode the key */ + if njs = self.decodeValue(); njs.Vt != types.V_STRING { + return types.ERR_INVALID_CHAR + } + + /* extract the key */ + idx := self.p - 1 + key := self.s[njs.Iv:idx] + + /* check for escape sequence */ + if njs.Ep != -1 { + if key, err = unquote(key); err != 0 { + return err + } + } + + /* expect a ':' delimiter */ + if err = self.delim(); err != 0 { + return err + } + + /* skip value */ + if key != match { + if _, err = self.skipFast(); err != 0 { + return err + } + } else { + return 0 + } + + /* check for EOF */ + self.p = self.lspace(self.p) + if self.p >= ns { + return types.ERR_EOF + } + + /* check for the next character */ + switch self.s[self.p] { + case ',': + self.p++ + case '}': + self.p++ + return _ERR_NOT_FOUND + default: + return types.ERR_INVALID_CHAR + } + } +} + +func (self *Parser) searchIndex(idx int) types.ParsingError { + ns := len(self.s) + if err := self.array(); err != 0 { + return err + } + + /* check for EOF */ + if self.p = self.lspace(self.p); self.p >= ns { + return types.ERR_EOF + } + + /* check for empty array */ + if self.s[self.p] == ']' { + self.p++ + return _ERR_NOT_FOUND + } + + var err types.ParsingError + /* allocate array space and parse every element */ + for i := 0; i < idx; i++ { + + /* decode the value */ + if _, err = self.skipFast(); err != 0 { + return err + } + + /* check for EOF */ + self.p = self.lspace(self.p) + if self.p >= ns { + return types.ERR_EOF + } + + /* check for the next character */ + switch self.s[self.p] { + case ',': + self.p++ + case ']': + self.p++ + return _ERR_NOT_FOUND + default: + return types.ERR_INVALID_CHAR + } + } + + return 0 +} + +func (self *Node) skipNextNode() *Node { + if !self.isLazy() { + return nil + } + + parser, stack := self.getParserAndArrayStack() + ret := &stack.v + sp := parser.p + ns := len(parser.s) + + /* check for EOF */ + if parser.p = parser.lspace(sp); parser.p >= ns { + return newSyntaxError(parser.syntaxError(types.ERR_EOF)) + } + + /* check for empty array */ + if parser.s[parser.p] == ']' { + parser.p++ + self.setArray(ret) + return nil + } + + var val Node + /* skip the value */ + if start, err := parser.skipFast(); err != 0 { + return newSyntaxError(parser.syntaxError(err)) + } else { + t := switchRawType(parser.s[start]) + if t == _V_NONE { + return newSyntaxError(parser.syntaxError(types.ERR_INVALID_CHAR)) + } + val = newRawNode(parser.s[start:parser.p], t, false) + } + + /* add the value to result */ + ret.Push(val) + self.l++ + parser.p = parser.lspace(parser.p) + + /* check for EOF */ + if parser.p >= ns { + return newSyntaxError(parser.syntaxError(types.ERR_EOF)) + } + + /* check for the next character */ + switch parser.s[parser.p] { + case ',': + parser.p++ + return ret.At(ret.Len()-1) + case ']': + parser.p++ + self.setArray(ret) + return ret.At(ret.Len()-1) + default: + return newSyntaxError(parser.syntaxError(types.ERR_INVALID_CHAR)) + } +} + +func (self *Node) skipNextPair() (*Pair) { + if !self.isLazy() { + return nil + } + + parser, stack := self.getParserAndObjectStack() + ret := &stack.v + sp := parser.p + ns := len(parser.s) + + /* check for EOF */ + if parser.p = parser.lspace(sp); parser.p >= ns { + return newErrorPair(parser.syntaxError(types.ERR_EOF)) + } + + /* check for empty object */ + if parser.s[parser.p] == '}' { + parser.p++ + self.setObject(ret) + return nil + } + + /* decode one pair */ + var val Node + var njs types.JsonState + var err types.ParsingError + + /* decode the key */ + if njs = parser.decodeValue(); njs.Vt != types.V_STRING { + return newErrorPair(parser.syntaxError(types.ERR_INVALID_CHAR)) + } + + /* extract the key */ + idx := parser.p - 1 + key := parser.s[njs.Iv:idx] + + /* check for escape sequence */ + if njs.Ep != -1 { + if key, err = unquote(key); err != 0 { + return newErrorPair(parser.syntaxError(err)) + } + } + + /* expect a ':' delimiter */ + if err = parser.delim(); err != 0 { + return newErrorPair(parser.syntaxError(err)) + } + + /* skip the value */ + if start, err := parser.skipFast(); err != 0 { + return newErrorPair(parser.syntaxError(err)) + } else { + t := switchRawType(parser.s[start]) + if t == _V_NONE { + return newErrorPair(parser.syntaxError(types.ERR_INVALID_CHAR)) + } + val = newRawNode(parser.s[start:parser.p], t, false) + } + + /* add the value to result */ + ret.Push(NewPair(key, val)) + self.l++ + parser.p = parser.lspace(parser.p) + + /* check for EOF */ + if parser.p >= ns { + return newErrorPair(parser.syntaxError(types.ERR_EOF)) + } + + /* check for the next character */ + switch parser.s[parser.p] { + case ',': + parser.p++ + return ret.At(ret.Len()-1) + case '}': + parser.p++ + self.setObject(ret) + return ret.At(ret.Len()-1) + default: + return newErrorPair(parser.syntaxError(types.ERR_INVALID_CHAR)) + } +} + + +/** Parser Factory **/ + +// Loads parse all json into interface{} +func Loads(src string) (int, interface{}, error) { + ps := &Parser{s: src} + np, err := ps.Parse() + + /* check for errors */ + if err != 0 { + return 0, nil, ps.ExportError(err) + } else { + x, err := np.Interface() + if err != nil { + return 0, nil, err + } + return ps.Pos(), x, nil + } +} + +// LoadsUseNumber parse all json into interface{}, with numeric nodes casted to json.Number +func LoadsUseNumber(src string) (int, interface{}, error) { + ps := &Parser{s: src} + np, err := ps.Parse() + + /* check for errors */ + if err != 0 { + return 0, nil, err + } else { + x, err := np.InterfaceUseNumber() + if err != nil { + return 0, nil, err + } + return ps.Pos(), x, nil + } +} + +// NewParser returns pointer of new allocated parser +func NewParser(src string) *Parser { + return &Parser{s: src} +} + +// NewParser returns new allocated parser +func NewParserObj(src string) Parser { + return Parser{s: src} +} + +// decodeNumber controls if parser decodes the number values instead of skip them +// WARN: once you set decodeNumber(true), please set decodeNumber(false) before you drop the parser +// otherwise the memory CANNOT be reused +func (self *Parser) decodeNumber(decode bool) { + if !decode && self.dbuf != nil { + types.FreeDbuf(self.dbuf) + self.dbuf = nil + return + } + if decode && self.dbuf == nil { + self.dbuf = types.NewDbuf() + } +} + +// ExportError converts types.ParsingError to std Error +func (self *Parser) ExportError(err types.ParsingError) error { + if err == _ERR_NOT_FOUND { + return ErrNotExist + } + return fmt.Errorf("%q", SyntaxError{ + Pos : self.p, + Src : self.s, + Code: err, + }.Description()) +} + +func backward(src string, i int) int { + for ; i>=0 && isSpace(src[i]); i-- {} + return i +} + + +func newRawNode(str string, typ types.ValueType, lock bool) Node { + ret := Node{ + t: typ | _V_RAW, + p: rt.StrPtr(str), + l: uint(len(str)), + } + if lock { + ret.m = new(sync.RWMutex) + } + return ret +} + +var typeJumpTable = [256]types.ValueType{ + '"' : types.V_STRING, + '-' : _V_NUMBER, + '0' : _V_NUMBER, + '1' : _V_NUMBER, + '2' : _V_NUMBER, + '3' : _V_NUMBER, + '4' : _V_NUMBER, + '5' : _V_NUMBER, + '6' : _V_NUMBER, + '7' : _V_NUMBER, + '8' : _V_NUMBER, + '9' : _V_NUMBER, + '[' : types.V_ARRAY, + 'f' : types.V_FALSE, + 'n' : types.V_NULL, + 't' : types.V_TRUE, + '{' : types.V_OBJECT, +} + +func switchRawType(c byte) types.ValueType { + return typeJumpTable[c] +} + +func (self *Node) loadt() types.ValueType { + return (types.ValueType)(atomic.LoadInt64(&self.t)) +} + +func (self *Node) lock() bool { + if m := self.m; m != nil { + m.Lock() + return true + } + return false +} + +func (self *Node) unlock() { + if m := self.m; m != nil { + m.Unlock() + } +} + +func (self *Node) rlock() bool { + if m := self.m; m != nil { + m.RLock() + return true + } + return false +} + +func (self *Node) runlock() { + if m := self.m; m != nil { + m.RUnlock() + } +} diff --git a/vendor/github.com/bytedance/sonic/ast/search.go b/vendor/github.com/bytedance/sonic/ast/search.go new file mode 100644 index 00000000..9a5fb942 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/ast/search.go @@ -0,0 +1,157 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ast + +import ( + `github.com/bytedance/sonic/internal/rt` + `github.com/bytedance/sonic/internal/native/types` +) + +// SearchOptions controls Searcher's behavior +type SearchOptions struct { + // ValidateJSON indicates the searcher to validate the entire JSON + ValidateJSON bool + + // CopyReturn indicates the searcher to copy the result JSON instead of refer from the input + // This can help to reduce memory usage if you cache the results + CopyReturn bool + + // ConcurrentRead indicates the searcher to return a concurrently-READ-safe node, + // including: GetByPath/Get/Index/GetOrIndex/Int64/Bool/Float64/String/Number/Interface/Array/Map/Raw/MarshalJSON + ConcurrentRead bool +} + +type Searcher struct { + parser Parser + SearchOptions +} + +func NewSearcher(str string) *Searcher { + return &Searcher{ + parser: Parser{ + s: str, + noLazy: false, + }, + SearchOptions: SearchOptions{ + ValidateJSON: true, + }, + } +} + +// GetByPathCopy search in depth from top json and returns a **Copied** json node at the path location +func (self *Searcher) GetByPathCopy(path ...interface{}) (Node, error) { + self.CopyReturn = true + return self.getByPath(path...) +} + +// GetByPathNoCopy search in depth from top json and returns a **Referenced** json node at the path location +// +// WARN: this search directly refer partial json from top json, which has faster speed, +// may consumes more memory. +func (self *Searcher) GetByPath(path ...interface{}) (Node, error) { + return self.getByPath(path...) +} + +func (self *Searcher) getByPath(path ...interface{}) (Node, error) { + var err types.ParsingError + var start int + + self.parser.p = 0 + start, err = self.parser.getByPath(self.ValidateJSON, path...) + if err != 0 { + // for compatibility with old version + if err == types.ERR_NOT_FOUND { + return Node{}, ErrNotExist + } + if err == types.ERR_UNSUPPORT_TYPE { + panic("path must be either int(>=0) or string") + } + return Node{}, self.parser.syntaxError(err) + } + + t := switchRawType(self.parser.s[start]) + if t == _V_NONE { + return Node{}, self.parser.ExportError(err) + } + + // copy string to reducing memory usage + var raw string + if self.CopyReturn { + raw = rt.Mem2Str([]byte(self.parser.s[start:self.parser.p])) + } else { + raw = self.parser.s[start:self.parser.p] + } + return newRawNode(raw, t, self.ConcurrentRead), nil +} + +// GetByPath searches a path and returns relaction and types of target +func _GetByPath(src string, path ...interface{}) (start int, end int, typ int, err error) { + p := NewParserObj(src) + s, e := p.getByPath(false, path...) + if e != 0 { + // for compatibility with old version + if e == types.ERR_NOT_FOUND { + return -1, -1, 0, ErrNotExist + } + if e == types.ERR_UNSUPPORT_TYPE { + panic("path must be either int(>=0) or string") + } + return -1, -1, 0, p.syntaxError(e) + } + + t := switchRawType(p.s[s]) + if t == _V_NONE { + return -1, -1, 0, ErrNotExist + } + if t == _V_NUMBER { + p.p = 1 + backward(p.s, p.p-1) + } + return s, p.p, int(t), nil +} + +// ValidSyntax check if a json has a valid JSON syntax, +// while not validate UTF-8 charset +func _ValidSyntax(json string) bool { + p := NewParserObj(json) + _, e := p.skip() + if e != 0 { + return false + } + if skipBlank(p.s, p.p) != -int(types.ERR_EOF) { + return false + } + return true +} + +// SkipFast skip a json value in fast-skip algs, +// while not strictly validate JSON syntax and UTF-8 charset. +func _SkipFast(src string, i int) (int, int, error) { + p := NewParserObj(src) + p.p = i + s, e := p.skipFast() + if e != 0 { + return -1, -1, p.ExportError(e) + } + t := switchRawType(p.s[s]) + if t == _V_NONE { + return -1, -1, ErrNotExist + } + if t == _V_NUMBER { + p.p = 1 + backward(p.s, p.p-1) + } + return s, p.p, nil +} diff --git a/vendor/github.com/bytedance/sonic/ast/stubs.go b/vendor/github.com/bytedance/sonic/ast/stubs.go new file mode 100644 index 00000000..9991cc89 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/ast/stubs.go @@ -0,0 +1,31 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ast + +import ( + "unsafe" + + "github.com/bytedance/sonic/internal/rt" +) + +//go:nosplit +func mem2ptr(s []byte) unsafe.Pointer { + return (*rt.GoSlice)(unsafe.Pointer(&s)).Ptr +} + +//go:linkname unquoteBytes encoding/json.unquoteBytes +func unquoteBytes(s []byte) (t []byte, ok bool) diff --git a/vendor/github.com/bytedance/sonic/ast/visitor.go b/vendor/github.com/bytedance/sonic/ast/visitor.go new file mode 100644 index 00000000..dc047851 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/ast/visitor.go @@ -0,0 +1,332 @@ +/* + * Copyright 2021 ByteDance Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package ast + +import ( + `encoding/json` + `errors` + + `github.com/bytedance/sonic/internal/native/types` +) + +// Visitor handles the callbacks during preorder traversal of a JSON AST. +// +// According to the JSON RFC8259, a JSON AST can be defined by +// the following rules without separator / whitespace tokens. +// +// JSON-AST = value +// value = false / null / true / object / array / number / string +// object = begin-object [ member *( member ) ] end-object +// member = string value +// array = begin-array [ value *( value ) ] end-array +// +type Visitor interface { + + // OnNull handles a JSON null value. + OnNull() error + + // OnBool handles a JSON true / false value. + OnBool(v bool) error + + // OnString handles a JSON string value. + OnString(v string) error + + // OnInt64 handles a JSON number value with int64 type. + OnInt64(v int64, n json.Number) error + + // OnFloat64 handles a JSON number value with float64 type. + OnFloat64(v float64, n json.Number) error + + // OnObjectBegin handles the beginning of a JSON object value with a + // suggested capacity that can be used to make your custom object container. + // + // After this point the visitor will receive a sequence of callbacks like + // [string, value, string, value, ......, ObjectEnd]. + // + // Note: + // 1. This is a recursive definition which means the value can + // also be a JSON object / array described by a sequence of callbacks. + // 2. The suggested capacity will be 0 if current object is empty. + // 3. Currently sonic use a fixed capacity for non-empty object (keep in + // sync with ast.Node) which might not be very suitable. This may be + // improved in future version. + OnObjectBegin(capacity int) error + + // OnObjectKey handles a JSON object key string in member. + OnObjectKey(key string) error + + // OnObjectEnd handles the ending of a JSON object value. + OnObjectEnd() error + + // OnArrayBegin handles the beginning of a JSON array value with a + // suggested capacity that can be used to make your custom array container. + // + // After this point the visitor will receive a sequence of callbacks like + // [value, value, value, ......, ArrayEnd]. + // + // Note: + // 1. This is a recursive definition which means the value can + // also be a JSON object / array described by a sequence of callbacks. + // 2. The suggested capacity will be 0 if current array is empty. + // 3. Currently sonic use a fixed capacity for non-empty array (keep in + // sync with ast.Node) which might not be very suitable. This may be + // improved in future version. + OnArrayBegin(capacity int) error + + // OnArrayEnd handles the ending of a JSON array value. + OnArrayEnd() error +} + +// VisitorOptions contains all Visitor's options. The default value is an +// empty VisitorOptions{}. +type VisitorOptions struct { + // OnlyNumber indicates parser to directly return number value without + // conversion, then the first argument of OnInt64 / OnFloat64 will always + // be zero. + OnlyNumber bool +} + +var defaultVisitorOptions = &VisitorOptions{} + +// Preorder decodes the whole JSON string and callbacks each AST node to visitor +// during preorder traversal. Any visitor method with an error returned will +// break the traversal and the given error will be directly returned. The opts +// argument can be reused after every call. +func Preorder(str string, visitor Visitor, opts *VisitorOptions) error { + if opts == nil { + opts = defaultVisitorOptions + } + // process VisitorOptions first to guarantee that all options will be + // constant during decoding and make options more readable. + var ( + optDecodeNumber = !opts.OnlyNumber + ) + + tv := &traverser{ + parser: Parser{ + s: str, + noLazy: true, + skipValue: false, + }, + visitor: visitor, + } + + if optDecodeNumber { + tv.parser.decodeNumber(true) + } + + err := tv.decodeValue() + + if optDecodeNumber { + tv.parser.decodeNumber(false) + } + return err +} + +type traverser struct { + parser Parser + visitor Visitor +} + +// NOTE: keep in sync with (*Parser).Parse method. +func (self *traverser) decodeValue() error { + switch val := self.parser.decodeValue(); val.Vt { + case types.V_EOF: + return types.ERR_EOF + case types.V_NULL: + return self.visitor.OnNull() + case types.V_TRUE: + return self.visitor.OnBool(true) + case types.V_FALSE: + return self.visitor.OnBool(false) + case types.V_STRING: + return self.decodeString(val.Iv, val.Ep) + case types.V_DOUBLE: + return self.visitor.OnFloat64(val.Dv, + json.Number(self.parser.s[val.Ep:self.parser.p])) + case types.V_INTEGER: + return self.visitor.OnInt64(val.Iv, + json.Number(self.parser.s[val.Ep:self.parser.p])) + case types.V_ARRAY: + return self.decodeArray() + case types.V_OBJECT: + return self.decodeObject() + default: + return types.ParsingError(-val.Vt) + } +} + +// NOTE: keep in sync with (*Parser).decodeArray method. +func (self *traverser) decodeArray() error { + sp := self.parser.p + ns := len(self.parser.s) + + /* allocate array space and parse every element */ + if err := self.visitor.OnArrayBegin(_DEFAULT_NODE_CAP); err != nil { + if err == VisitOPSkip { + // NOTICE: for user needs to skip entiry object + self.parser.p -= 1 + if _, e := self.parser.skipFast(); e != 0 { + return e + } + return self.visitor.OnArrayEnd() + } + return err + } + + /* check for EOF */ + self.parser.p = self.parser.lspace(sp) + if self.parser.p >= ns { + return types.ERR_EOF + } + + /* check for empty array */ + if self.parser.s[self.parser.p] == ']' { + self.parser.p++ + return self.visitor.OnArrayEnd() + } + + for { + /* decode the value */ + if err := self.decodeValue(); err != nil { + return err + } + self.parser.p = self.parser.lspace(self.parser.p) + + /* check for EOF */ + if self.parser.p >= ns { + return types.ERR_EOF + } + + /* check for the next character */ + switch self.parser.s[self.parser.p] { + case ',': + self.parser.p++ + case ']': + self.parser.p++ + return self.visitor.OnArrayEnd() + default: + return types.ERR_INVALID_CHAR + } + } +} + +// NOTE: keep in sync with (*Parser).decodeObject method. +func (self *traverser) decodeObject() error { + sp := self.parser.p + ns := len(self.parser.s) + + /* allocate object space and decode each pair */ + if err := self.visitor.OnObjectBegin(_DEFAULT_NODE_CAP); err != nil { + if err == VisitOPSkip { + // NOTICE: for user needs to skip entiry object + self.parser.p -= 1 + if _, e := self.parser.skipFast(); e != 0 { + return e + } + return self.visitor.OnObjectEnd() + } + return err + } + + /* check for EOF */ + self.parser.p = self.parser.lspace(sp) + if self.parser.p >= ns { + return types.ERR_EOF + } + + /* check for empty object */ + if self.parser.s[self.parser.p] == '}' { + self.parser.p++ + return self.visitor.OnObjectEnd() + } + + for { + var njs types.JsonState + var err types.ParsingError + + /* decode the key */ + if njs = self.parser.decodeValue(); njs.Vt != types.V_STRING { + return types.ERR_INVALID_CHAR + } + + /* extract the key */ + idx := self.parser.p - 1 + key := self.parser.s[njs.Iv:idx] + + /* check for escape sequence */ + if njs.Ep != -1 { + if key, err = unquote(key); err != 0 { + return err + } + } + + if err := self.visitor.OnObjectKey(key); err != nil { + return err + } + + /* expect a ':' delimiter */ + if err = self.parser.delim(); err != 0 { + return err + } + + /* decode the value */ + if err := self.decodeValue(); err != nil { + return err + } + + self.parser.p = self.parser.lspace(self.parser.p) + + /* check for EOF */ + if self.parser.p >= ns { + return types.ERR_EOF + } + + /* check for the next character */ + switch self.parser.s[self.parser.p] { + case ',': + self.parser.p++ + case '}': + self.parser.p++ + return self.visitor.OnObjectEnd() + default: + return types.ERR_INVALID_CHAR + } + } +} + +// NOTE: keep in sync with (*Parser).decodeString method. +func (self *traverser) decodeString(iv int64, ep int) error { + p := self.parser.p - 1 + s := self.parser.s[iv:p] + + /* fast path: no escape sequence */ + if ep == -1 { + return self.visitor.OnString(s) + } + + /* unquote the string */ + out, err := unquote(s) + if err != 0 { + return err + } + return self.visitor.OnString(out) +} + +// If visitor return this error on `OnObjectBegin()` or `OnArrayBegin()`, +// the transverer will skip entiry object or array +var VisitOPSkip = errors.New("") diff --git a/vendor/github.com/bytedance/sonic/encoder/encoder_compat.go b/vendor/github.com/bytedance/sonic/encoder/encoder_compat.go new file mode 100644 index 00000000..d48e99b1 --- /dev/null +++ b/vendor/github.com/bytedance/sonic/encoder/encoder_compat.go @@ -0,0 +1,262 @@ +// +build !amd64,!arm64 go1.25 !go1.17 arm64,!go1.20 + +/* +* Copyright 2023 ByteDance Inc. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package encoder + +import ( + `io` + `bytes` + `encoding/json` + `reflect` + + `github.com/bytedance/sonic/option` + `github.com/bytedance/sonic/internal/compat` +) + +func init() { + compat.Warn("sonic/encoder") +} + +// EnableFallback indicates if encoder use fallback +const EnableFallback = true + +// Options is a set of encoding options. +type Options uint64 + +const ( + bitSortMapKeys = iota + bitEscapeHTML + bitCompactMarshaler + bitNoQuoteTextMarshaler + bitNoNullSliceOrMap + bitValidateString + bitNoValidateJSONMarshaler + bitNoEncoderNewline + + // used for recursive compile + bitPointerValue = 63 +) + +const ( + // SortMapKeys indicates that the keys of a map needs to be sorted + // before serializing into JSON. + // WARNING: This hurts performance A LOT, USE WITH CARE. + SortMapKeys Options = 1 << bitSortMapKeys + + // EscapeHTML indicates encoder to escape all HTML characters + // after serializing into JSON (see https://pkg.go.dev/encoding/json#HTMLEscape). + // WARNING: This hurts performance A LOT, USE WITH CARE. + EscapeHTML Options = 1 << bitEscapeHTML + + // CompactMarshaler indicates that the output JSON from json.Marshaler + // is always compact and needs no validation + CompactMarshaler Options = 1 << bitCompactMarshaler + + // NoQuoteTextMarshaler indicates that the output text from encoding.TextMarshaler + // is always escaped string and needs no quoting + NoQuoteTextMarshaler Options = 1 << bitNoQuoteTextMarshaler + + // NoNullSliceOrMap indicates all empty Array or Object are encoded as '[]' or '{}', + // instead of 'null' + NoNullSliceOrMap Options = 1 << bitNoNullSliceOrMap + + // ValidateString indicates that encoder should validate the input string + // before encoding it into JSON. + ValidateString Options = 1 << bitValidateString + + // NoValidateJSONMarshaler indicates that the encoder should not validate the output string + // after encoding the JSONMarshaler to JSON. + NoValidateJSONMarshaler Options = 1 << bitNoValidateJSONMarshaler + + // NoEncoderNewline indicates that the encoder should not add a newline after every message + NoEncoderNewline Options = 1 << bitNoEncoderNewline + + // CompatibleWithStd is used to be compatible with std encoder. + CompatibleWithStd Options = SortMapKeys | EscapeHTML | CompactMarshaler +) + +// Encoder represents a specific set of encoder configurations. +type Encoder struct { + Opts Options + prefix string + indent string +} + +// Encode returns the JSON encoding of v. +func (self *Encoder) Encode(v interface{}) ([]byte, error) { + if self.indent != "" || self.prefix != "" { + return EncodeIndented(v, self.prefix, self.indent, self.Opts) + } + return Encode(v, self.Opts) +} + +// SortKeys enables the SortMapKeys option. +func (self *Encoder) SortKeys() *Encoder { + self.Opts |= SortMapKeys + return self +} + +// SetEscapeHTML specifies if option EscapeHTML opens +func (self *Encoder) SetEscapeHTML(f bool) { + if f { + self.Opts |= EscapeHTML + } else { + self.Opts &= ^EscapeHTML + } +} + +// SetValidateString specifies if option ValidateString opens +func (self *Encoder) SetValidateString(f bool) { + if f { + self.Opts |= ValidateString + } else { + self.Opts &= ^ValidateString + } +} + +// SetNoValidateJSONMarshaler specifies if option NoValidateJSONMarshaler opens +func (self *Encoder) SetNoValidateJSONMarshaler(f bool) { + if f { + self.Opts |= NoValidateJSONMarshaler + } else { + self.Opts &= ^NoValidateJSONMarshaler + } +} + +// SetNoEncoderNewline specifies if option NoEncoderNewline opens +func (self *Encoder) SetNoEncoderNewline(f bool) { + if f { + self.Opts |= NoEncoderNewline + } else { + self.Opts &= ^NoEncoderNewline + } +} + +// SetCompactMarshaler specifies if option CompactMarshaler opens +func (self *Encoder) SetCompactMarshaler(f bool) { + if f { + self.Opts |= CompactMarshaler + } else { + self.Opts &= ^CompactMarshaler + } +} + +// SetNoQuoteTextMarshaler specifies if option NoQuoteTextMarshaler opens +func (self *Encoder) SetNoQuoteTextMarshaler(f bool) { + if f { + self.Opts |= NoQuoteTextMarshaler + } else { + self.Opts &= ^NoQuoteTextMarshaler + } +} + +// SetIndent instructs the encoder to format each subsequent encoded +// value as if indented by the package-level function EncodeIndent(). +// Calling SetIndent("", "") disables indentation. +func (enc *Encoder) SetIndent(prefix, indent string) { + enc.prefix = prefix + enc.indent = indent +} + +// Quote returns the JSON-quoted version of s. +func Quote(s string) string { + /* check for empty string */ + if s == "" { + return `""` + } + + out, _ := json.Marshal(s) + return string(out) +} + +// Encode returns the JSON encoding of val, encoded with opts. +func Encode(val interface{}, opts Options) ([]byte, error) { + return json.Marshal(val) +} + +// EncodeInto is like Encode but uses a user-supplied buffer instead of allocating +// a new one. +func EncodeInto(buf *[]byte, val interface{}, opts Options) error { + if buf == nil { + panic("user-supplied buffer buf is nil") + } + w := bytes.NewBuffer(*buf) + enc := json.NewEncoder(w) + enc.SetEscapeHTML((opts & EscapeHTML) != 0) + err := enc.Encode(val) + *buf = w.Bytes() + l := len(*buf) + if l > 0 && (opts & NoEncoderNewline != 0) && (*buf)[l-1] == '\n' { + *buf = (*buf)[:l-1] + } + return err +} + +// HTMLEscape appends to dst the JSON-encoded src with <, >, &, U+2028 and U+2029 +// characters inside string literals changed to \u003c, \u003e, \u0026, \u2028, \u2029 +// so that the JSON will be safe to embed inside HTML