-
Notifications
You must be signed in to change notification settings - Fork 131
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Add Base64Decode * Remove unnecessary ignore Expr equality context
- Loading branch information
Showing
5 changed files
with
146 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
from typing import TYPE_CHECKING | ||
from enum import Enum | ||
|
||
from pyteal.types import TealType, require_type | ||
from pyteal.errors import verifyFieldVersion | ||
from pyteal.ir import TealOp, Op, TealBlock | ||
from pyteal.ast.expr import Expr | ||
from pyteal.ast.leafexpr import LeafExpr | ||
|
||
if TYPE_CHECKING: | ||
from pyteal.compiler import CompileOptions | ||
|
||
|
||
class Base64Encoding(Enum): | ||
# fmt: off | ||
# id | name | min version | ||
url = (0, "URLEncoding", 7) | ||
std = (1, "StdEncoding", 7) | ||
# fmt: on | ||
|
||
def __init__(self, id: int, name: str, min_version: int) -> None: | ||
self.id = id | ||
self.arg_name = name | ||
self.min_version = min_version | ||
|
||
|
||
Base64Encoding.__module__ = "pyteal" | ||
|
||
|
||
class Base64Decode(LeafExpr): | ||
"""An expression that decodes a base64-encoded byte string according to a specific encoding. | ||
See [RFC 4648](https://rfc-editor.org/rfc/rfc4648.html#section-4) (sections 4 and 5) for information on specifications. | ||
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. | ||
""" | ||
|
||
def __init__(self, encoding: Base64Encoding, base64: Expr) -> None: | ||
super().__init__() | ||
self.encoding = encoding | ||
|
||
require_type(base64, TealType.bytes) | ||
self.base64 = base64 | ||
|
||
def __teal__(self, options: "CompileOptions"): | ||
verifyFieldVersion( | ||
self.encoding.arg_name, self.encoding.min_version, options.version | ||
) | ||
|
||
op = TealOp(self, Op.base64_decode, self.encoding.arg_name) | ||
return TealBlock.FromOp(options, op, self.base64) | ||
|
||
def __str__(self): | ||
return "(Base64Decode {})".format(self.encoding.arg_name) | ||
|
||
def type_of(self): | ||
return TealType.bytes | ||
|
||
@classmethod | ||
def url(cls, base64: Expr) -> "Base64Decode": | ||
"""Decode a base64-encoded byte string according to the URL encoding. | ||
Refer to the `Base64Decode` class documentation for more information. | ||
Args: | ||
base64: A base64-encoded byte string. | ||
""" | ||
return cls(Base64Encoding.url, base64) | ||
|
||
@classmethod | ||
def std(cls, base64: Expr) -> "Base64Decode": | ||
"""Decode a base64-encoded byte string according to the Standard encoding. | ||
Refer to the `Base64Decode` class documentation for more information. | ||
Args: | ||
base64: A base64-encoded byte string. | ||
""" | ||
return cls(Base64Encoding.std, base64) | ||
|
||
|
||
Base64Decode.__module__ = "pyteal" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import pytest | ||
|
||
import pyteal as pt | ||
|
||
teal6Options = pt.CompileOptions(version=6) | ||
teal7Options = pt.CompileOptions(version=7) | ||
|
||
|
||
def test_base64decode_std(): | ||
arg = pt.Bytes("aGVsbG8gd29ybGQ=") | ||
expr = pt.Base64Decode.std(arg) | ||
assert expr.type_of() == pt.TealType.bytes | ||
|
||
expected = pt.TealSimpleBlock( | ||
[ | ||
pt.TealOp(arg, pt.Op.byte, '"aGVsbG8gd29ybGQ="'), | ||
pt.TealOp(expr, pt.Op.base64_decode, "StdEncoding"), | ||
] | ||
) | ||
|
||
actual, _ = expr.__teal__(teal7Options) | ||
actual.addIncoming() | ||
actual = pt.TealBlock.NormalizeBlocks(actual) | ||
|
||
assert actual == expected | ||
|
||
with pytest.raises(pt.TealInputError): | ||
expr.__teal__(teal6Options) | ||
|
||
|
||
def test_base64decode_url(): | ||
arg = pt.Bytes("aGVsbG8gd29ybGQ") | ||
expr = pt.Base64Decode.url(arg) | ||
assert expr.type_of() == pt.TealType.bytes | ||
|
||
expected = pt.TealSimpleBlock( | ||
[ | ||
pt.TealOp(arg, pt.Op.byte, '"aGVsbG8gd29ybGQ"'), | ||
pt.TealOp(expr, pt.Op.base64_decode, "URLEncoding"), | ||
] | ||
) | ||
|
||
actual, _ = expr.__teal__(teal7Options) | ||
actual.addIncoming() | ||
actual = pt.TealBlock.NormalizeBlocks(actual) | ||
|
||
assert actual == expected | ||
|
||
with pytest.raises(pt.TealInputError): | ||
expr.__teal__(teal6Options) | ||
|
||
|
||
def test_base64decode_invalid(): | ||
with pytest.raises(pt.TealTypeError): | ||
pt.Base64Decode.std(pt.Int(0)) | ||
with pytest.raises(pt.TealTypeError): | ||
pt.Base64Decode.url(pt.Int(0)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters