summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuval Adam <_@yuv.al>2020-02-01 12:59:51 +0200
committerYuval Adam <_@yuv.al>2020-02-01 12:59:51 +0200
commitb0668017d1d6266d0420d82a0c6467138d1e1b21 (patch)
tree53ba9a0664b86ae054424da634cb112e2dea41c0
parent8ecb86371b2cb99e0460b15320c2ffbd77ced138 (diff)
Run black on entire codebase
-rw-r--r--setup.py38
-rw-r--r--tests/test_parse.py67
-rw-r--r--tests/test_viewstate.py21
-rw-r--r--viewstate/__init__.py1
-rw-r--r--viewstate/__main__.py4
-rw-r--r--viewstate/exceptions.py2
-rw-r--r--viewstate/parse.py59
-rw-r--r--viewstate/viewstate.py15
8 files changed, 106 insertions, 101 deletions
diff --git a/setup.py b/setup.py
index b8dffad..5d413b7 100644
--- a/setup.py
+++ b/setup.py
@@ -1,28 +1,30 @@
from pathlib import Path
from setuptools import setup, find_packages
-with open(str(Path(__file__).resolve().parents[0] / 'README.rst'), encoding='utf-8') as f:
+with open(
+ str(Path(__file__).resolve().parents[0] / "README.rst"), encoding="utf-8"
+) as f:
long_description = f.read()
setup(
- name='viewstate',
- author='Yuval Adam',
- author_email='_@yuv.al',
- version='0.4.3',
- description='ASP.NET View State Decoder',
+ name="viewstate",
+ author="Yuval Adam",
+ author_email="_@yuv.al",
+ version="0.4.3",
+ description="ASP.NET View State Decoder",
long_description=long_description,
- url='https://github.com/yuvadm/viewstate',
- license='MIT',
- python_requires='>=3.5.0',
- packages=find_packages(exclude=['docs', 'tests']),
+ url="https://github.com/yuvadm/viewstate",
+ license="MIT",
+ python_requires=">=3.5.0",
+ packages=find_packages(exclude=["docs", "tests"]),
classifiers=[
- 'License :: OSI Approved :: MIT License',
- 'Programming Language :: Python',
- 'Programming Language :: Python :: 3.5',
- 'Programming Language :: Python :: 3.6',
- 'Programming Language :: Python :: 3.7',
- 'Programming Language :: Python :: 3.8',
- 'Programming Language :: Python :: Implementation :: CPython',
- 'Programming Language :: Python :: Implementation :: PyPy'
+ "License :: OSI Approved :: MIT License",
+ "Programming Language :: Python",
+ "Programming Language :: Python :: 3.5",
+ "Programming Language :: Python :: 3.6",
+ "Programming Language :: Python :: 3.7",
+ "Programming Language :: Python :: 3.8",
+ "Programming Language :: Python :: Implementation :: CPython",
+ "Programming Language :: Python :: Implementation :: PyPy",
],
)
diff --git a/tests/test_parse.py b/tests/test_parse.py
index f9d445f..fea1fd4 100644
--- a/tests/test_parse.py
+++ b/tests/test_parse.py
@@ -8,76 +8,83 @@ from viewstate import *
class TestParse(object):
def test_const_value(self):
- vs = ViewState(raw=b'\xff\x01\x67')
+ vs = ViewState(raw=b"\xff\x01\x67")
assert vs.decode() is True
def test_int_value(self):
- vs = ViewState(raw=b'\xff\x01\x02\x88\x01')
+ vs = ViewState(raw=b"\xff\x01\x02\x88\x01")
assert vs.decode() == 136
def test_string_value(self):
- s = 'abcdefghij'
- vs = ViewState(raw=b'\xff\x01\x05' + bytes([len(s)]) + s.encode())
+ s = "abcdefghij"
+ vs = ViewState(raw=b"\xff\x01\x05" + bytes([len(s)]) + s.encode())
assert vs.decode() == s
def test_simple_dict(self):
- vs = ViewState(raw=b'\xff\x01\x18\x02\x05\x01a\x05\x01b\x05\x01c\x05\x01d')
- assert vs.decode() == {'a': 'b', 'c': 'd'}
+ vs = ViewState(raw=b"\xff\x01\x18\x02\x05\x01a\x05\x01b\x05\x01c\x05\x01d")
+ assert vs.decode() == {"a": "b", "c": "d"}
def test_simple_list(self):
- vs = ViewState(raw=b'\xff\x01\x16\x05\x05\x01a\x05\x01b\x05\x01c\x05\x01d\x05\x01e')
- assert vs.decode() == ['a', 'b', 'c', 'd', 'e']
+ vs = ViewState(
+ raw=b"\xff\x01\x16\x05\x05\x01a\x05\x01b\x05\x01c\x05\x01d\x05\x01e"
+ )
+ assert vs.decode() == ["a", "b", "c", "d", "e"]
def test_simple_pair(self):
- vs = ViewState(raw=b'\xff\x01\x0f\x67\x68')
+ vs = ViewState(raw=b"\xff\x01\x0f\x67\x68")
assert vs.decode() == (True, False)
def test_simple_triplet(self):
- vs = ViewState(raw=b'\xff\x01\x10\x67\x68\x67')
+ vs = ViewState(raw=b"\xff\x01\x10\x67\x68\x67")
assert vs.decode() == (True, False, True)
- @pytest.mark.skip(reason='Color parsing is not yet supported')
+ @pytest.mark.skip(reason="Color parsing is not yet supported")
def test_color(self):
- vs = ViewState(raw=b'\xff\x01\n\x91\x01')
- assert vs.decode() == 'Color: Salmon'
+ vs = ViewState(raw=b"\xff\x01\n\x91\x01")
+ assert vs.decode() == "Color: Salmon"
def test_rgba(self):
- vs = ViewState(raw=b'\xff\x01\x09\x10\x20\x30\x40')
- assert vs.decode() == 'RGBA(16,32,48,64)'
+ vs = ViewState(raw=b"\xff\x01\x09\x10\x20\x30\x40")
+ assert vs.decode() == "RGBA(16,32,48,64)"
def test_formatted_string(self):
vs = ViewState()
- s1 = 'System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'
- s2 = '6111733106'
- vs.raw = b'\xff\x01()' + bytes([len(s1)]) + s1.encode() + bytes([len(s2)]) + s2.encode()
- assert vs.decode() == 'Formatted string: {} type ref {}'.format(s2, s1)
+ s1 = "System.Int64, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
+ s2 = "6111733106"
+ vs.raw = (
+ b"\xff\x01()"
+ + bytes([len(s1)])
+ + s1.encode()
+ + bytes([len(s2)])
+ + s2.encode()
+ )
+ assert vs.decode() == "Formatted string: {} type ref {}".format(s2, s1)
- @pytest.mark.skip(reason='Datetime parsing not yet supported')
+ @pytest.mark.skip(reason="Datetime parsing not yet supported")
def test_datetime(self):
vs = ViewState()
- vs.raw = b'\xff\x01\x06\x000Po\x9b\x87\xd5\x88'
+ vs.raw = b"\xff\x01\x06\x000Po\x9b\x87\xd5\x88"
assert vs.decode() == datetime(2018, 3, 11, 22)
- vs.raw = b'\xff\x01\x06\x00\xf0\xb9\x99d\x88\xd5\x88'
+ vs.raw = b"\xff\x01\x06\x00\xf0\xb9\x99d\x88\xd5\x88"
assert vs.decode() == datetime(2018, 3, 12, 22)
def test_complex_pair(self):
vs = ViewState()
- vs.raw = b'\xff\x01\x0f\x67\x0f\x68\x66'
+ vs.raw = b"\xff\x01\x0f\x67\x0f\x68\x66"
assert vs.decode() == (True, (False, 0))
- vs.raw = b'\xff\x01\x0f\x0f\x67\x68\x66'
+ vs.raw = b"\xff\x01\x0f\x0f\x67\x68\x66"
assert vs.decode() == ((True, False), 0)
- vs.raw = b'\xff\x01\x0f\x0f\x67\x05\x061q2w3e\x66'
- assert vs.decode() == ((True, '1q2w3e'), 0)
+ vs.raw = b"\xff\x01\x0f\x0f\x67\x05\x061q2w3e\x66"
+ assert vs.decode() == ((True, "1q2w3e"), 0)
def test_parse_unknown(self):
with pytest.raises(ViewStateException):
- vs = ViewState(raw=b'\xff\x01\x99\x99\x99')
+ vs = ViewState(raw=b"\xff\x01\x99\x99\x99")
assert vs.decode()
def test_parse_samples(self):
- for root, dirs, files in walk('tests/samples'):
+ for root, dirs, files in walk("tests/samples"):
for f in files:
- with open(join(root, f), 'r') as t:
+ with open(join(root, f), "r") as t:
vs = ViewState(t.read())
_ = vs.decode()
-
diff --git a/tests/test_viewstate.py b/tests/test_viewstate.py
index 9cc9285..628e1e0 100644
--- a/tests/test_viewstate.py
+++ b/tests/test_viewstate.py
@@ -6,43 +6,42 @@ from viewstate import *
class TestViewState(object):
-
def test_blank(self):
vs = ViewState()
assert not vs.is_valid()
def test_is_valid(self):
- for root, dirs, files in walk('tests/samples'):
+ for root, dirs, files in walk("tests/samples"):
for f in files:
- with open(join(root, f), 'r') as t:
+ with open(join(root, f), "r") as t:
vs = ViewState(t.read())
assert vs.is_valid() is True
def test_invalid_base64(self):
with pytest.raises(ViewStateException):
- vs = ViewState('hello')
+ vs = ViewState("hello")
def test_invalid_decode(self):
with pytest.raises(ViewStateException):
- vs = ViewState(raw=b'\x01\x02')
+ vs = ViewState(raw=b"\x01\x02")
vs.decode()
def test_no_signature(self):
- vs = ViewState(raw=b'\xff\x01e')
+ vs = ViewState(raw=b"\xff\x01e")
vs.decode()
assert vs.mac is None
assert vs.signature is None
def test_macs(self):
MAC_LENGTHS = {
- 'hmac_sha1': 20,
- 'hmac_sha256': 32,
- 'unknown': 5 # could be any other value
+ "hmac_sha1": 20,
+ "hmac_sha256": 32,
+ "unknown": 5, # could be any other value
}
for mac, n in MAC_LENGTHS.items():
- sig = b'\x55' * n # not a real signature, just testing length
- vs = ViewState(raw=b'\xff\x01d' + sig)
+ sig = b"\x55" * n # not a real signature, just testing length
+ vs = ViewState(raw=b"\xff\x01d" + sig)
vs.decode()
assert vs.mac == mac
assert vs.signature == sig
diff --git a/viewstate/__init__.py b/viewstate/__init__.py
index b6858bb..f3a6d11 100644
--- a/viewstate/__init__.py
+++ b/viewstate/__init__.py
@@ -1,3 +1,2 @@
from .viewstate import ViewState
from .exceptions import ViewStateException
-
diff --git a/viewstate/__main__.py b/viewstate/__main__.py
index e600cb4..395304f 100644
--- a/viewstate/__main__.py
+++ b/viewstate/__main__.py
@@ -15,6 +15,6 @@ def main(raw=False):
pp.pprint(vs.decode())
-if __name__ == '__main__':
- raw = len(sys.argv) > 1 and sys.argv[1] == '-r'
+if __name__ == "__main__":
+ raw = len(sys.argv) > 1 and sys.argv[1] == "-r"
main(raw)
diff --git a/viewstate/exceptions.py b/viewstate/exceptions.py
index d9f6eda..66b756f 100644
--- a/viewstate/exceptions.py
+++ b/viewstate/exceptions.py
@@ -1,4 +1,2 @@
-
-
class ViewStateException(Exception):
pass
diff --git a/viewstate/parse.py b/viewstate/parse.py
index ef788e6..0db6224 100644
--- a/viewstate/parse.py
+++ b/viewstate/parse.py
@@ -4,16 +4,17 @@ from .exceptions import ViewStateException
class ParserMeta(type):
- '''
+ """
Parser metaclass is used to register each of the parser subclasses `marker` field
This field is used to dynamically select the right class for parsing a given byte array
- '''
+ """
+
def __init__(cls, name, bases, namespace):
super(ParserMeta, cls).__init__(name, bases, namespace)
- if not hasattr(cls, 'registry'):
+ if not hasattr(cls, "registry"):
cls.registry = {}
- if hasattr(cls, 'marker'):
- marker = getattr(cls, 'marker')
+ if hasattr(cls, "marker"):
+ marker = getattr(cls, "marker")
if type(marker) not in (tuple, list):
marker = [marker]
for m in marker:
@@ -21,21 +22,21 @@ class ParserMeta(type):
class Parser(metaclass=ParserMeta):
- '''
+ """
Main parser class delegates parsing according to current byte marker
Performs lookup on metaclass registry
- '''
+ """
+
@staticmethod
def parse(b):
marker, remain = b[0], b[1:]
try:
return Parser.registry[marker].parse(remain)
except KeyError:
- raise ViewStateException('Unknown marker {}'.format(marker))
+ raise ViewStateException("Unknown marker {}".format(marker))
class Const(Parser):
-
@classmethod
def parse(cls, remain):
return cls.const, remain
@@ -48,7 +49,7 @@ class NoneConst(Const):
class EmptyConst(Const):
marker = 0x65
- const = ''
+ const = ""
class ZeroConst(Const):
@@ -67,17 +68,17 @@ class FalseConst(Const):
class Integer(Parser):
- marker = (0x02, 0x2b)
+ marker = (0x02, 0x2B)
@staticmethod
def parse(b):
n = 0
bits = 0
i = 0
- while (bits < 32):
+ while bits < 32:
tmp = b[i]
i += 1
- n |= (tmp & 0x7f) << bits
+ n |= (tmp & 0x7F) << bits
if not (tmp & 0x80):
return n, b[i:]
bits += 7
@@ -85,7 +86,7 @@ class Integer(Parser):
class String(Parser):
- marker = (0x05, 0x1e, 0x2a, 0x29)
+ marker = (0x05, 0x1E, 0x2A, 0x29)
@staticmethod
def parse(b):
@@ -96,29 +97,29 @@ class String(Parser):
class Enum(Parser):
- marker = 0x0b
+ marker = 0x0B
@staticmethod
def parse(b):
enum, remain = Parser.parse(b)
val, remain = Integer.parse(remain) # unsure about this part
- final = 'Enum: {}, val: {}'.format(enum, val)
+ final = "Enum: {}, val: {}".format(enum, val)
return final, remain
class Color(Parser):
- marker = 0x0a
+ marker = 0x0A
@staticmethod
def parse(b):
# No specification for color parsing, we're assuming it's just two bytes
# One example we have is that `\n\x91\x01` is parsed as `Color: Color [Salmon]`
# Originally reported in https://github.com/yuvadm/viewstate/issues/2
- return 'Color: unknown', b[2:]
+ return "Color: unknown", b[2:]
class Pair(Parser):
- marker = 0x0f
+ marker = 0x0F
@staticmethod
def parse(b):
@@ -143,17 +144,17 @@ class Datetime(Parser):
@staticmethod
def parse(b):
- #print([x for x in b[:8]])
+ # print([x for x in b[:8]])
return datetime(2000, 1, 1), b[8:]
class Unit(Parser):
- marker = 0x1b
+ marker = 0x1B
@staticmethod
def parse(b):
- #print([x for x in b[:12]])
- return 'Unit: ', b[12:]
+ # print([x for x in b[:12]])
+ return "Unit: ", b[12:]
class RGBA(Parser):
@@ -161,7 +162,7 @@ class RGBA(Parser):
@staticmethod
def parse(b):
- return 'RGBA({},{},{},{})'.format(*b[:4]), b[4:]
+ return "RGBA({},{},{},{})".format(*b[:4]), b[4:]
class StringArray(Parser):
@@ -173,7 +174,7 @@ class StringArray(Parser):
l = []
for _ in range(n):
if not remain[0]:
- val, remain = '', remain[1:]
+ val, remain = "", remain[1:]
else:
val, remain = String.parse(remain)
l.append(val)
@@ -194,12 +195,12 @@ class Array(Parser):
class StringRef(Parser):
- marker = 0x1f
+ marker = 0x1F
@staticmethod
def parse(b):
val, remain = Integer.parse(b)
- return 'Stringref #{}'.format(val), remain
+ return "Stringref #{}".format(val), remain
class FormattedString(Parser):
@@ -209,11 +210,11 @@ class FormattedString(Parser):
def parse(b):
s1, remain = Parser.parse(b)
s2, remain = String.parse(remain)
- return 'Formatted string: {} type ref {}'.format(s2, s1), remain
+ return "Formatted string: {} type ref {}".format(s2, s1), remain
class SparseArray(Parser):
- marker = 0x3c
+ marker = 0x3C
@staticmethod
def parse(b):
diff --git a/viewstate/viewstate.py b/viewstate/viewstate.py
index a992161..e43a0e5 100644
--- a/viewstate/viewstate.py
+++ b/viewstate/viewstate.py
@@ -6,14 +6,13 @@ from .parse import Parser
class ViewState(object):
-
def __init__(self, base64=None, raw=None):
if base64:
self.base64 = base64
try:
self.raw = b64decode(self.base64)
except BinAsciiError as bae:
- raise ViewStateException('Cannot decode base64 input')
+ raise ViewStateException("Cannot decode base64 input")
elif raw:
self.raw = raw
self.decoded = None
@@ -29,8 +28,8 @@ class ViewState(object):
return self.raw[2:]
def is_valid(self):
- FORMAT_MARKER = b'\xff'
- VERSION_MARKER = b'\x01'
+ FORMAT_MARKER = b"\xff"
+ VERSION_MARKER = b"\x01"
PREAMBLE = FORMAT_MARKER + VERSION_MARKER
try:
@@ -40,17 +39,17 @@ class ViewState(object):
def decode(self):
if not self.is_valid():
- raise ViewStateException('Cannot decode invalid viewstate, bad preamble')
+ raise ViewStateException("Cannot decode invalid viewstate, bad preamble")
self.decoded, self.remainder = Parser.parse(self.body)
if self.remainder:
if len(self.remainder) == 20:
- self.mac = 'hmac_sha1'
+ self.mac = "hmac_sha1"
elif len(self.remainder) == 32:
- self.mac = 'hmac_sha256'
+ self.mac = "hmac_sha256"
else:
- self.mac = 'unknown'
+ self.mac = "unknown"
self.signature = self.remainder
return self.decoded