From 019da28a8e620d4e2b5ac828af9c9118c0821c40 Mon Sep 17 00:00:00 2001 From: Yuval Adam <_@yuv.al> Date: Mon, 19 Feb 2018 15:17:38 +0100 Subject: More structure changes --- LICENSE | 21 +++++++++++++++++++++ LICENSE.txt | 21 --------------------- setup.cfg | 5 +++++ setup.py | 14 ++++++++++++++ test.py | 28 ---------------------------- tests/__init__.py | 28 ++++++++++++++++++++++++++++ viewstate.py | 47 ----------------------------------------------- viewstate/__init__.py | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 115 insertions(+), 96 deletions(-) create mode 100644 LICENSE delete mode 100644 LICENSE.txt create mode 100644 setup.cfg create mode 100644 setup.py delete mode 100644 test.py create mode 100644 tests/__init__.py delete mode 100644 viewstate.py create mode 100644 viewstate/__init__.py diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3d3c2fa --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Yuval Adam + +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/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index 3d3c2fa..0000000 --- a/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2018 Yuval Adam - -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/setup.cfg b/setup.cfg new file mode 100644 index 0000000..60bd34d --- /dev/null +++ b/setup.cfg @@ -0,0 +1,5 @@ +[bdist_wheel] +universal = 1 + +[metadata] +license_file = LICENSE \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..461c120 --- /dev/null +++ b/setup.py @@ -0,0 +1,14 @@ +from setuptools import setup, find_packages + +with open(path.join(here, 'README.rst'), encoding='utf-8') as f: + long_description = f.read() + +setup( + name='viewstate', + version='0.0.1', + description='.NET viewstate decoder', + long_description=long_description, + homepage='https://github.com/yuvadm/viewstate', + author='Yuval Adam', + packages=find_packages(exclude=['docs', 'tests']), +) diff --git a/test.py b/test.py deleted file mode 100644 index f203615..0000000 --- a/test.py +++ /dev/null @@ -1,28 +0,0 @@ -import unittest - -from viewstate import ViewState - -class TestViewState(unittest.TestCase): - - def test_blank(self): - vs = ViewState() - self.assertFalse(vs.is_valid()) - - def test_is_valid(self): - with open('samples/ngcs.sample', 'r') as f: - vs = ViewState(f.read()) - self.assertTrue(vs.is_valid()) - - def test_invalid_decode(self): - with self.assertRaises(Exception): - vs = ViewState() - vs.raw = b'\x01\x02' - vs.decode() - - def test_parse_const_value(self): - vs = ViewState() - vs.raw = b'\xff\x01\x67' - self.assertEqual(vs.decode(), True) - -if __name__ == '__main__': - unittest.main() diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..f203615 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1,28 @@ +import unittest + +from viewstate import ViewState + +class TestViewState(unittest.TestCase): + + def test_blank(self): + vs = ViewState() + self.assertFalse(vs.is_valid()) + + def test_is_valid(self): + with open('samples/ngcs.sample', 'r') as f: + vs = ViewState(f.read()) + self.assertTrue(vs.is_valid()) + + def test_invalid_decode(self): + with self.assertRaises(Exception): + vs = ViewState() + vs.raw = b'\x01\x02' + vs.decode() + + def test_parse_const_value(self): + vs = ViewState() + vs.raw = b'\xff\x01\x67' + self.assertEqual(vs.decode(), True) + +if __name__ == '__main__': + unittest.main() diff --git a/viewstate.py b/viewstate.py deleted file mode 100644 index b75cd37..0000000 --- a/viewstate.py +++ /dev/null @@ -1,47 +0,0 @@ -from base64 import b64decode, b64encode - - -CONSTS = { - 100: {}, - 101: '', - 102: 0, - 103: True, - 104: False -} - -def parse_const(b): - return CONSTS.get(b, None) - -def parse(b): - assert type(b) == bytes().__class__ - if len(b) == 1: - return parse_const(b[0]) - return None - - -class ViewState(object): - - def __init__(self, base64=''): - self.base64 = base64 - self.raw = b64decode(self.base64) - self.decoded = None - - @property - def preamble(self): - return self.raw[:2] - - @property - def body(self): - return self.raw[2:] - - def is_valid(self): - format_marker = b'\xff' - version_marker = b'\x01' - preamble = format_marker + version_marker - return self.preamble == preamble - - def decode(self): - if not self.is_valid(): - raise Exception('Cannot decode invalid viewstate, bad preamble') - self.decoded = parse(self.body) - return self.decoded diff --git a/viewstate/__init__.py b/viewstate/__init__.py new file mode 100644 index 0000000..b75cd37 --- /dev/null +++ b/viewstate/__init__.py @@ -0,0 +1,47 @@ +from base64 import b64decode, b64encode + + +CONSTS = { + 100: {}, + 101: '', + 102: 0, + 103: True, + 104: False +} + +def parse_const(b): + return CONSTS.get(b, None) + +def parse(b): + assert type(b) == bytes().__class__ + if len(b) == 1: + return parse_const(b[0]) + return None + + +class ViewState(object): + + def __init__(self, base64=''): + self.base64 = base64 + self.raw = b64decode(self.base64) + self.decoded = None + + @property + def preamble(self): + return self.raw[:2] + + @property + def body(self): + return self.raw[2:] + + def is_valid(self): + format_marker = b'\xff' + version_marker = b'\x01' + preamble = format_marker + version_marker + return self.preamble == preamble + + def decode(self): + if not self.is_valid(): + raise Exception('Cannot decode invalid viewstate, bad preamble') + self.decoded = parse(self.body) + return self.decoded -- cgit v1.3.1