diff --git a/cmd/opdoc/tmLanguage.go b/cmd/opdoc/tmLanguage.go index 3f5aa8503a..199514b40c 100644 --- a/cmd/opdoc/tmLanguage.go +++ b/cmd/opdoc/tmLanguage.go @@ -175,7 +175,7 @@ func buildSyntaxHighlight() *tmLanguage { // For these, accumulate into allArithmetics, // and only add to keyword.Patterns later, when all // have been collected. - case "Arithmetic", "Byte Array Slicing", "Byte Array Arithmetic", + case "Arithmetic", "Byte Array Manipulation", "Byte Array Arithmetic", "Byte Array Logic", "Inner Transactions": escape := map[rune]bool{ '*': true, diff --git a/data/transactions/logic/README.md b/data/transactions/logic/README.md index b76869db1b..e1ca8efa1a 100644 --- a/data/transactions/logic/README.md +++ b/data/transactions/logic/README.md @@ -165,7 +165,7 @@ various sizes. | `extract_uint16` | pop a byte-array A and integer B. Extract a range of bytes from A starting at B up to but not including B+2, convert bytes as big endian and push the uint64 result. If B+2 is larger than the array length, the program fails | | `extract_uint32` | pop a byte-array A and integer B. Extract a range of bytes from A starting at B up to but not including B+4, convert bytes as big endian and push the uint64 result. If B+4 is larger than the array length, the program fails | | `extract_uint64` | pop a byte-array A and integer B. Extract a range of bytes from A starting at B up to but not including B+8, convert bytes as big endian and push the uint64 result. If B+8 is larger than the array length, the program fails | -| `base64_decode e` | decode X which was base64-encoded using _encoding alphabet_ E. Fail if X is not base64 encoded with alphabet E | +| `base64_decode e` | decode X which was base64-encoded using _encoding_ E. Fail if X is not base64 encoded with encoding E | These opcodes take byte-array values that are interpreted as big-endian unsigned integers. For mathematical operators, the diff --git a/data/transactions/logic/README_in.md b/data/transactions/logic/README_in.md index 494dd5776f..a70a2b45e7 100644 --- a/data/transactions/logic/README_in.md +++ b/data/transactions/logic/README_in.md @@ -90,7 +90,7 @@ various sizes. ### Byte Array Manipulation -@@ Byte_Array_Slicing.md @@ +@@ Byte_Array_Manipulation.md @@ These opcodes take byte-array values that are interpreted as big-endian unsigned integers. For mathematical operators, the diff --git a/data/transactions/logic/TEAL_opcodes.md b/data/transactions/logic/TEAL_opcodes.md index fe667cc781..69a86492c4 100644 --- a/data/transactions/logic/TEAL_opcodes.md +++ b/data/transactions/logic/TEAL_opcodes.md @@ -856,14 +856,14 @@ When A is a uint64, index 0 is the least significant bit. Setting bit 3 to 1 on ## base64_decode e -- Opcode: 0x5c {uint8 alphabet index} +- Opcode: 0x5c {uint8 encoding index} - Pops: *... stack*, []byte - Pushes: []byte -- decode X which was base64-encoded using _encoding alphabet_ E. Fail if X is not base64 encoded with alphabet E +- decode X which was base64-encoded using _encoding_ E. Fail if X is not base64 encoded with encoding E - **Cost**: 25 - LogicSigVersion >= 6 -decodes X using the base64 encoding alphabet E. Specify the alphabet with an immediate arg either as URL and Filename Safe (`URLAlph`) or Standard (`StdAlph`). See RFC 4648 (sections 4 and 5) +Decodes X using the base64 encoding E. Specify the encoding with an immediate arg either as URL and Filename Safe (`URLEncoding`) or Standard (`StdEncoding`). See RFC 4648 (sections 4 and 5). It is assumed that the encoding ends with the exact number of `=` padding characters as required by the RFC. When padding occurs, any unused pad bits in the encoding must be set to zero or the decoding will fail. The special cases of `\n` and `\r` are allowed but completely ignored. An error will result when attempting to decode a string with a character that is not in the encoding alphabet or not one of `=`, `\r`, or `\n`. ## balance diff --git a/data/transactions/logic/assembler.go b/data/transactions/logic/assembler.go index 34151d4c0c..613a93650a 100644 --- a/data/transactions/logic/assembler.go +++ b/data/transactions/logic/assembler.go @@ -1249,20 +1249,20 @@ func assembleBase64Decode(ops *OpStream, spec *OpSpec, args []string) error { return ops.errorf("%s expects one argument", spec.Name) } - alph, ok := base64AlphabetSpecByName[args[0]] + encoding, ok := base64EncodingSpecByName[args[0]] if !ok { - return ops.errorf("%s unknown alphabet: %#v", spec.Name, args[0]) + return ops.errorf("%s unknown encoding: %#v", spec.Name, args[0]) } - if alph.version > ops.Version { + if encoding.version > ops.Version { //nolint:errcheck // we continue to maintain typestack - ops.errorf("%s %s available in version %d. Missed #pragma version?", spec.Name, args[0], alph.version) + ops.errorf("%s %s available in version %d. Missed #pragma version?", spec.Name, args[0], encoding.version) } - val := alph.field + val := encoding.field ops.pending.WriteByte(spec.Opcode) ops.pending.WriteByte(uint8(val)) - ops.trace("%s (%s)", alph.field, alph.ftype) - ops.returns(alph.ftype) + ops.trace("%s (%s)", encoding.field, encoding.ftype) + ops.returns(encoding.ftype) return nil } @@ -2698,10 +2698,10 @@ func disBase64Decode(dis *disassembleState, spec *OpSpec) (string, error) { } dis.nextpc = dis.pc + 2 b64dArg := dis.program[dis.pc+1] - if int(b64dArg) >= len(base64AlphabetNames) { + if int(b64dArg) >= len(base64EncodingNames) { return "", fmt.Errorf("invalid base64_decode arg index %d at pc=%d", b64dArg, dis.pc) } - return fmt.Sprintf("%s %s", spec.Name, base64AlphabetNames[b64dArg]), nil + return fmt.Sprintf("%s %s", spec.Name, base64EncodingNames[b64dArg]), nil } type disInfo struct { diff --git a/data/transactions/logic/assembler_test.go b/data/transactions/logic/assembler_test.go index 19abfefb23..1c56ab7a4b 100644 --- a/data/transactions/logic/assembler_test.go +++ b/data/transactions/logic/assembler_test.go @@ -344,7 +344,7 @@ itxna Logs 3 const v6Nonsense = v5Nonsense + ` itxn_next -base64_decode URLAlph +base64_decode URLEncoding ` var nonsense = map[uint64]string{ diff --git a/data/transactions/logic/doc.go b/data/transactions/logic/doc.go index ff258f01e3..4887f45f3c 100644 --- a/data/transactions/logic/doc.go +++ b/data/transactions/logic/doc.go @@ -133,7 +133,7 @@ var opDocByName = map[string]string{ "extract_uint16": "pop a byte-array A and integer B. Extract a range of bytes from A starting at B up to but not including B+2, convert bytes as big endian and push the uint64 result. If B+2 is larger than the array length, the program fails", "extract_uint32": "pop a byte-array A and integer B. Extract a range of bytes from A starting at B up to but not including B+4, convert bytes as big endian and push the uint64 result. If B+4 is larger than the array length, the program fails", "extract_uint64": "pop a byte-array A and integer B. Extract a range of bytes from A starting at B up to but not including B+8, convert bytes as big endian and push the uint64 result. If B+8 is larger than the array length, the program fails", - "base64_decode": "decode X which was base64-encoded using _encoding alphabet_ E. Fail if X is not base64 encoded with alphabet E", + "base64_decode": "decode X which was base64-encoded using _encoding_ E. Fail if X is not base64 encoded with encoding E", "balance": "get balance for account A, in microalgos. The balance is observed after the effects of previous transactions in the group, and after the fee for the current transaction is deducted.", "min_balance": "get minimum required balance for account A, in microalgos. Required balance is affected by [ASA](https://developer.algorand.org/docs/features/asa/#assets-overview) and [App](https://developer.algorand.org/docs/features/asc1/stateful/#minimum-balance-requirement-for-a-smart-contract) usage. When creating or opting into an app, the minimum balance grows before the app code runs, therefore the increase is visible there. When deleting or closing out, the minimum balance decreases after the app executes.", @@ -231,7 +231,7 @@ var opcodeImmediateNotes = map[string]string{ "ecdsa_pk_decompress": "{uint8 curve index}", "ecdsa_pk_recover": "{uint8 curve index}", - "base64_decode": "{uint8 alphabet index}", + "base64_decode": "{uint8 encoding index}", } // OpImmediateNote returns a short string about immediate data which follows the op byte @@ -286,7 +286,7 @@ var opDocExtras = map[string]string{ "itxn_begin": "`itxn_begin` initializes Sender to the application address; Fee to the minimum allowable, taking into account MinTxnFee and credit from overpaying in earlier transactions; FirstValid/LastValid to the values in the top-level transaction, and all other fields to zero values.", "itxn_field": "`itxn_field` fails if X is of the wrong type for F, including a byte array of the wrong size for use as an address when F is an address field. `itxn_field` also fails if X is an account or asset that does not appear in `txn.Accounts` or `txn.ForeignAssets` of the top-level transaction. (Setting addresses in asset creation are exempted from this requirement.)", "itxn_submit": "`itxn_submit` resets the current transaction so that it can not be resubmitted. A new `itxn_begin` is required to prepare another inner transaction.", - "base64_decode": "decodes X using the base64 encoding alphabet E. Specify the alphabet with an immediate arg either as URL and Filename Safe (`URLAlph`) or Standard (`StdAlph`). See RFC 4648 (sections 4 and 5)", + "base64_decode": "Decodes X using the base64 encoding E. Specify the encoding with an immediate arg either as URL and Filename Safe (`URLEncoding`) or Standard (`StdEncoding`). See RFC 4648 (sections 4 and 5). It is assumed that the encoding ends with the exact number of `=` padding characters as required by the RFC. When padding occurs, any unused pad bits in the encoding must be set to zero or the decoding will fail. The special cases of `\\n` and `\\r` are allowed but completely ignored. An error will result when attempting to decode a string with a character that is not in the encoding alphabet or not one of `=`, `\\r`, or `\\n`.", } // OpDocExtra returns extra documentation text about an op @@ -298,14 +298,14 @@ func OpDocExtra(opName string) string { // here is the order args opcodes are presented, so place related // opcodes consecutively, even if their opcode values are not. var OpGroups = map[string][]string{ - "Arithmetic": {"sha256", "keccak256", "sha512_256", "ed25519verify", "ecdsa_verify", "ecdsa_pk_recover", "ecdsa_pk_decompress", "+", "-", "/", "*", "<", ">", "<=", ">=", "&&", "||", "shl", "shr", "sqrt", "bitlen", "exp", "==", "!=", "!", "len", "itob", "btoi", "%", "|", "&", "^", "~", "mulw", "addw", "divmodw", "expw", "getbit", "setbit", "getbyte", "setbyte", "concat"}, - "Byte Array Slicing": {"substring", "substring3", "extract", "extract3", "extract_uint16", "extract_uint32", "extract_uint64", "base64_decode"}, - "Byte Array Arithmetic": {"b+", "b-", "b/", "b*", "b<", "b>", "b<=", "b>=", "b==", "b!=", "b%"}, - "Byte Array Logic": {"b|", "b&", "b^", "b~"}, - "Loading Values": {"intcblock", "intc", "intc_0", "intc_1", "intc_2", "intc_3", "pushint", "bytecblock", "bytec", "bytec_0", "bytec_1", "bytec_2", "bytec_3", "pushbytes", "bzero", "arg", "arg_0", "arg_1", "arg_2", "arg_3", "args", "txn", "gtxn", "txna", "txnas", "gtxna", "gtxnas", "gtxns", "gtxnsa", "gtxnsas", "global", "load", "loads", "store", "stores", "gload", "gloads", "gaid", "gaids"}, - "Flow Control": {"err", "bnz", "bz", "b", "return", "pop", "dup", "dup2", "dig", "cover", "uncover", "swap", "select", "assert", "callsub", "retsub"}, - "State Access": {"balance", "min_balance", "app_opted_in", "app_local_get", "app_local_get_ex", "app_global_get", "app_global_get_ex", "app_local_put", "app_global_put", "app_local_del", "app_global_del", "asset_holding_get", "asset_params_get", "app_params_get", "log"}, - "Inner Transactions": {"itxn_begin", "itxn_next", "itxn_field", "itxn_submit", "itxn", "itxna"}, + "Arithmetic": {"sha256", "keccak256", "sha512_256", "ed25519verify", "ecdsa_verify", "ecdsa_pk_recover", "ecdsa_pk_decompress", "+", "-", "/", "*", "<", ">", "<=", ">=", "&&", "||", "shl", "shr", "sqrt", "bitlen", "exp", "==", "!=", "!", "len", "itob", "btoi", "%", "|", "&", "^", "~", "mulw", "addw", "divmodw", "expw", "getbit", "setbit", "getbyte", "setbyte", "concat"}, + "Byte Array Manipulation": {"substring", "substring3", "extract", "extract3", "extract_uint16", "extract_uint32", "extract_uint64", "base64_decode"}, + "Byte Array Arithmetic": {"b+", "b-", "b/", "b*", "b<", "b>", "b<=", "b>=", "b==", "b!=", "b%"}, + "Byte Array Logic": {"b|", "b&", "b^", "b~"}, + "Loading Values": {"intcblock", "intc", "intc_0", "intc_1", "intc_2", "intc_3", "pushint", "bytecblock", "bytec", "bytec_0", "bytec_1", "bytec_2", "bytec_3", "pushbytes", "bzero", "arg", "arg_0", "arg_1", "arg_2", "arg_3", "args", "txn", "gtxn", "txna", "txnas", "gtxna", "gtxnas", "gtxns", "gtxnsa", "gtxnsas", "global", "load", "loads", "store", "stores", "gload", "gloads", "gaid", "gaids"}, + "Flow Control": {"err", "bnz", "bz", "b", "return", "pop", "dup", "dup2", "dig", "cover", "uncover", "swap", "select", "assert", "callsub", "retsub"}, + "State Access": {"balance", "min_balance", "app_opted_in", "app_local_get", "app_local_get_ex", "app_global_get", "app_global_get_ex", "app_local_put", "app_global_put", "app_local_del", "app_global_del", "asset_holding_get", "asset_params_get", "app_params_get", "log"}, + "Inner Transactions": {"itxn_begin", "itxn_next", "itxn_field", "itxn_submit", "itxn", "itxna"}, } // OpCost indicates the cost of an operation over the range of diff --git a/data/transactions/logic/eval.go b/data/transactions/logic/eval.go index cc7006f03a..842403e9cb 100644 --- a/data/transactions/logic/eval.go +++ b/data/transactions/logic/eval.go @@ -4047,15 +4047,15 @@ func base64Decode(encoded []byte, encoding *base64.Encoding) ([]byte, error) { func opBase64Decode(cx *EvalContext) { last := len(cx.stack) - 1 - alphabetField := Base64Alphabet(cx.program[cx.pc+1]) - fs, ok := base64AlphabetSpecByField[alphabetField] + encodingField := Base64Encoding(cx.program[cx.pc+1]) + fs, ok := base64EncodingSpecByField[encodingField] if !ok || fs.version > cx.version { - cx.err = fmt.Errorf("invalid base64_decode alphabet %d", alphabetField) + cx.err = fmt.Errorf("invalid base64_decode encoding %d", encodingField) return } encoding := base64.URLEncoding - if alphabetField == StdAlph { + if encodingField == StdEncoding { encoding = base64.StdEncoding } cx.stack[last].Bytes, cx.err = base64Decode(cx.stack[last].Bytes, encoding) diff --git a/data/transactions/logic/evalStateful_test.go b/data/transactions/logic/evalStateful_test.go index 2098d3af41..b8e368bf30 100644 --- a/data/transactions/logic/evalStateful_test.go +++ b/data/transactions/logic/evalStateful_test.go @@ -2392,7 +2392,7 @@ func TestReturnTypes(t *testing.T) { "itxn": "itxn_begin; int pay; itxn_field TypeEnum; itxn_submit; itxn CreatedAssetID", // This next one is a cop out. Can't use itxna Logs until we have inner appl "itxna": "itxn_begin; int pay; itxn_field TypeEnum; itxn_submit; itxn NumLogs", - "base64_decode": `pushbytes "YWJjMTIzIT8kKiYoKSctPUB+"; base64_decode StdAlph; pushbytes "abc123!?$*&()'-=@~"; ==; pushbytes "YWJjMTIzIT8kKiYoKSctPUB-"; base64_decode URLAlph; pushbytes "abc123!?$*&()'-=@~"; ==; &&; assert`, + "base64_decode": `pushbytes "YWJjMTIzIT8kKiYoKSctPUB+"; base64_decode StdEncoding; pushbytes "abc123!?$*&()'-=@~"; ==; pushbytes "YWJjMTIzIT8kKiYoKSctPUB-"; base64_decode URLEncoding; pushbytes "abc123!?$*&()'-=@~"; ==; &&; assert`, } // these require special input data and tested separately diff --git a/data/transactions/logic/eval_test.go b/data/transactions/logic/eval_test.go index c374a3022e..ef92c6ce54 100644 --- a/data/transactions/logic/eval_test.go +++ b/data/transactions/logic/eval_test.go @@ -3738,15 +3738,15 @@ func BenchmarkBase64Decode(b *testing.B) { "keccak256", "sha256", "sha512_256", - "base64_decode StdAlph", - "base64_decode URLAlph", + "base64_decode StdEncoding", + "base64_decode URLEncoding", } benches := [][]string{} for i, tag := range tags { for _, op := range ops { testName := op encoded := stds[i] - if op == "base64_decode URLAlph" { + if op == "base64_decode URLEncoding" { encoded = urls[i] } if len(op) > 0 { @@ -4961,14 +4961,16 @@ func TestPcDetails(t *testing.T) { var minB64DecodeVersion uint64 = 6 type b64DecodeTestCase struct { - Encoded string - IsURL bool - Decoded string - Error error + Encoded string + IsURL bool + HasExtraNLs bool + Decoded string + Error error } var testCases = []b64DecodeTestCase{ {"TU9CWS1ESUNLOwoKb3IsIFRIRSBXSEFMRS4KCgpCeSBIZXJtYW4gTWVsdmlsbGU=", + false, false, `MOBY-DICK; @@ -4980,6 +4982,7 @@ By Herman Melville`, }, {"TU9CWS1ESUNLOwoKb3IsIFRIRSBXSEFMRS4KCgpCeSBIZXJtYW4gTWVsdmlsbGU=", true, + false, `MOBY-DICK; or, THE WHALE. @@ -4988,10 +4991,51 @@ or, THE WHALE. By Herman Melville`, nil, }, - {"YWJjMTIzIT8kKiYoKSctPUB+", false, "abc123!?$*&()'-=@~", nil}, - {"YWJjMTIzIT8kKiYoKSctPUB-", true, "abc123!?$*&()'-=@~", nil}, - {"YWJjMTIzIT8kKiYoKSctPUB+", true, "", base64.CorruptInputError(23)}, - {"YWJjMTIzIT8kKiYoKSctPUB-", false, "", base64.CorruptInputError(23)}, + {"YWJjMTIzIT8kKiYoKSctPUB+", false, false, "abc123!?$*&()'-=@~", nil}, + {"YWJjMTIzIT8kKiYoKSctPUB-", true, false, "abc123!?$*&()'-=@~", nil}, + {"YWJjMTIzIT8kKiYoKSctPUB+", true, false, "", base64.CorruptInputError(23)}, + {"YWJjMTIzIT8kKiYoKSctPUB-", false, false, "", base64.CorruptInputError(23)}, + + // try extra ='s and various whitespace: + {"", false, false, "", nil}, + {"", true, false, "", nil}, + {"=", false, true, "", base64.CorruptInputError(0)}, + {"=", true, true, "", base64.CorruptInputError(0)}, + {" ", false, true, "", base64.CorruptInputError(0)}, + {" ", true, true, "", base64.CorruptInputError(0)}, + {"\t", false, true, "", base64.CorruptInputError(0)}, + {"\t", true, true, "", base64.CorruptInputError(0)}, + {"\r", false, true, "", nil}, + {"\r", true, true, "", nil}, + {"\n", false, true, "", nil}, + {"\n", true, true, "", nil}, + + {"YWJjMTIzIT8kKiYoKSctPUB+\n", false, true, "abc123!?$*&()'-=@~", nil}, + {"YWJjMTIzIT8kKiYoKSctPUB-\n", true, true, "abc123!?$*&()'-=@~", nil}, + {"YWJjMTIzIT8kK\riYoKSctPUB+\n", false, true, "abc123!?$*&()'-=@~", nil}, + {"YWJjMTIzIT8kK\riYoKSctPUB-\n", true, true, "abc123!?$*&()'-=@~", nil}, + {"\n\rYWJjMTIzIT8\rkKiYoKSctPUB+\n", false, true, "abc123!?$*&()'-=@~", nil}, + {"\n\rYWJjMTIzIT8\rkKiYoKSctPUB-\n", true, true, "abc123!?$*&()'-=@~", nil}, + + // padding and extra legal whitespace + {"SQ==", false, false, "I", nil}, + {"SQ==", true, false, "I", nil}, + {"\rS\r\nQ=\n=\r\r\n", false, true, "I", nil}, + {"\rS\r\nQ=\n=\r\r\n", true, true, "I", nil}, + + // Padding necessary? - Yes it is! And exactly the expected place and amount. + {"SQ==", false, false, "I", nil}, + {"SQ==", true, false, "I", nil}, + {"S=Q=", false, false, "", base64.CorruptInputError(1)}, + {"S=Q=", true, false, "", base64.CorruptInputError(1)}, + {"=SQ=", false, false, "", base64.CorruptInputError(0)}, + {"=SQ=", true, false, "", base64.CorruptInputError(0)}, + {"SQ", false, false, "", base64.CorruptInputError(0)}, + {"SQ", true, false, "", base64.CorruptInputError(0)}, + {"SQ=", false, false, "", base64.CorruptInputError(3)}, + {"SQ=", true, false, "", base64.CorruptInputError(3)}, + {"SQ===", false, false, "", base64.CorruptInputError(4)}, + {"SQ===", true, false, "", base64.CorruptInputError(4)}, } func TestBase64DecodeFunc(t *testing.T) { @@ -5003,10 +5047,14 @@ func TestBase64DecodeFunc(t *testing.T) { if testCase.IsURL { encoding = base64.URLEncoding } - encoding = encoding.Strict() + // sanity check: + if testCase.Error == nil && !testCase.HasExtraNLs { + require.Equal(t, testCase.Encoded, encoding.EncodeToString([]byte(testCase.Decoded))) + } + decoded, err := base64Decode([]byte(testCase.Encoded), encoding) + require.Equal(t, testCase.Error, err, fmt.Sprintf("Error (%s): case decode [%s] -> [%s]", err, testCase.Encoded, testCase.Decoded)) require.Equal(t, []byte(testCase.Decoded), decoded) - require.Equal(t, testCase.Error, err) } } @@ -5026,9 +5074,9 @@ base64_decode %s args := []b64DecodeTestArgs{} for _, testCase := range testCases { if testCase.Error == nil { - field := "StdAlph" + field := "StdEncoding" if testCase.IsURL { - field = "URLAlph" + field = "URLEncoding" } source := fmt.Sprintf(sourceTmpl, minB64DecodeVersion, field) ops, err := AssembleStringWithVersion(source, minB64DecodeVersion) diff --git a/data/transactions/logic/fields.go b/data/transactions/logic/fields.go index 37ef079cc5..9863427735 100644 --- a/data/transactions/logic/fields.go +++ b/data/transactions/logic/fields.go @@ -23,7 +23,7 @@ import ( "github.com/algorand/go-algorand/protocol" ) -//go:generate stringer -type=TxnField,GlobalField,AssetParamsField,AppParamsField,AssetHoldingField,OnCompletionConstType,EcdsaCurve,Base64Alphabet -output=fields_string.go +//go:generate stringer -type=TxnField,GlobalField,AssetParamsField,AppParamsField,AssetHoldingField,OnCompletionConstType,EcdsaCurve,Base64Encoding -output=fields_string.go // TxnField is an enum type for `txn` and `gtxn` type TxnField int @@ -448,37 +448,37 @@ func (s ecDsaCurveNameSpecMap) getExtraFor(name string) (extra string) { return } -// Base64Alphabet is an enum for the `base64decode` opcode -type Base64Alphabet int +// Base64Encoding is an enum for the `base64decode` opcode +type Base64Encoding int const ( - // URLAlph represents the base64url alphabet defined in https://www.rfc-editor.org/rfc/rfc4648.html - URLAlph Base64Alphabet = iota - // StdAlph represents the standard alphabet of the RFC - StdAlph + // URLEncoding represents the base64url encoding defined in https://www.rfc-editor.org/rfc/rfc4648.html + URLEncoding Base64Encoding = iota + // StdEncoding represents the standard encoding of the RFC + StdEncoding invalidBase64Alphabet ) // After running `go generate` these strings will be available: -var base64AlphabetNames [2]string = [...]string{URLAlph.String(), StdAlph.String()} +var base64EncodingNames [2]string = [...]string{URLEncoding.String(), StdEncoding.String()} -type base64AlphabetSpec struct { - field Base64Alphabet +type base64EncodingSpec struct { + field Base64Encoding ftype StackType version uint64 } -var base64AlphbetSpecs = []base64AlphabetSpec{ - {URLAlph, StackBytes, 6}, - {StdAlph, StackBytes, 6}, +var base64EncodingSpecs = []base64EncodingSpec{ + {URLEncoding, StackBytes, 6}, + {StdEncoding, StackBytes, 6}, } -var base64AlphabetSpecByField map[Base64Alphabet]base64AlphabetSpec -var base64AlphabetSpecByName base64AlphabetSpecMap +var base64EncodingSpecByField map[Base64Encoding]base64EncodingSpec +var base64EncodingSpecByName base64EncodingSpecMap -type base64AlphabetSpecMap map[string]base64AlphabetSpec +type base64EncodingSpecMap map[string]base64EncodingSpec -func (s base64AlphabetSpecMap) getExtraFor(name string) (extra string) { +func (s base64EncodingSpecMap) getExtraFor(name string) (extra string) { // Uses 6 here because base64_decode fields were introduced in 6 if s[name].version > 6 { extra = fmt.Sprintf("LogicSigVersion >= %d.", s[name].version) @@ -719,14 +719,14 @@ func init() { ecdsaCurveSpecByName[ahfn] = ecdsaCurveSpecByField[EcdsaCurve(i)] } - base64AlphabetSpecByField = make(map[Base64Alphabet]base64AlphabetSpec, len(base64AlphabetNames)) - for _, s := range base64AlphbetSpecs { - base64AlphabetSpecByField[s.field] = s + base64EncodingSpecByField = make(map[Base64Encoding]base64EncodingSpec, len(base64EncodingNames)) + for _, s := range base64EncodingSpecs { + base64EncodingSpecByField[s.field] = s } - base64AlphabetSpecByName = make(base64AlphabetSpecMap, len(base64AlphabetNames)) - for i, alphname := range base64AlphabetNames { - base64AlphabetSpecByName[alphname] = base64AlphabetSpecByField[Base64Alphabet(i)] + base64EncodingSpecByName = make(base64EncodingSpecMap, len(base64EncodingNames)) + for i, encoding := range base64EncodingNames { + base64EncodingSpecByName[encoding] = base64EncodingSpecByField[Base64Encoding(i)] } AssetHoldingFieldNames = make([]string, int(invalidAssetHoldingField)) diff --git a/data/transactions/logic/fields_string.go b/data/transactions/logic/fields_string.go index 5861dedc17..ffe5ed5b3c 100644 --- a/data/transactions/logic/fields_string.go +++ b/data/transactions/logic/fields_string.go @@ -1,4 +1,4 @@ -// Code generated by "stringer -type=TxnField,GlobalField,AssetParamsField,AppParamsField,AssetHoldingField,OnCompletionConstType,EcdsaCurve,Base64Alphabet -output=fields_string.go"; DO NOT EDIT. +// Code generated by "stringer -type=TxnField,GlobalField,AssetParamsField,AppParamsField,AssetHoldingField,OnCompletionConstType,EcdsaCurve,Base64Encoding -output=fields_string.go"; DO NOT EDIT. package logic @@ -231,18 +231,18 @@ func _() { // An "invalid array index" compiler error signifies that the constant values have changed. // Re-run the stringer command to generate them again. var x [1]struct{} - _ = x[URLAlph-0] - _ = x[StdAlph-1] + _ = x[URLEncoding-0] + _ = x[StdEncoding-1] _ = x[invalidBase64Alphabet-2] } -const _Base64Alphabet_name = "URLAlphStdAlphinvalidBase64Alphabet" +const _Base64Encoding_name = "URLEncodingStdEncodinginvalidBase64Alphabet" -var _Base64Alphabet_index = [...]uint8{0, 7, 14, 35} +var _Base64Encoding_index = [...]uint8{0, 11, 22, 43} -func (i Base64Alphabet) String() string { - if i < 0 || i >= Base64Alphabet(len(_Base64Alphabet_index)-1) { - return "Base64Alphabet(" + strconv.FormatInt(int64(i), 10) + ")" +func (i Base64Encoding) String() string { + if i < 0 || i >= Base64Encoding(len(_Base64Encoding_index)-1) { + return "Base64Encoding(" + strconv.FormatInt(int64(i), 10) + ")" } - return _Base64Alphabet_name[_Base64Alphabet_index[i]:_Base64Alphabet_index[i+1]] + return _Base64Encoding_name[_Base64Encoding_index[i]:_Base64Encoding_index[i+1]] }