{ "info": { "author": "Dan Sokolsky", "author_email": "dan@pelotoncycle.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 2", "Programming Language :: Python :: 3", "Topic :: Software Development" ], "description": "Safe Int\n=======================\n\nConstruct integer within a given range to prevent DoS attacks.\n\nPulling data from the Internet and feeding it to Python's builtin int function exposes you to a potential DoS attack. Python supports arbitrary precision integers. Unlike other languages like C++, Java or even Javascript which will eventually overflow, Python can represent any number you have the memory to store. For instance, in the following code::\n\n s = '9' * 1000000 # Generate a string with one million 9s\n i = int(s)\n\nPython keeps on going and will stuff 10^1000000 - 1 into i after 7 seconds of CPU work and 400kb of RAM. 7 seconds during which your gevent based web server cannot perform a context switch and service other requests. A single machine running a few hundred greenlets on a cable modem would be enough to cripple a web server with APIs that accepts integers.\n\nsafeint.int is a drop-in replacement for int to help parse untrusted data coming from the Internet. You use it like this::\n\n import safeint\n\n\n def my_controller():\n foo = safeint.int(bottle.request.query.foo) \n\n\nBy default safeint.int will raise a ValueError if your input string is too long. The default is 10 digits, but you can raise or lower that as your application requires with the keyword parameter digits. So for example, safeint.int(foo, digits=2) limits you to numbers in the range -9 to 99 inclusive. \n\nsafeint.int also supports a few extra parameters and features beyond what int normally supports. If you pass it None or an empty string it returns None, saving you from the hassle of writing code that looks like this:: \n\n if bottle.request.query.foo is None:\n foo = None\n else:\n foo = int(bottle.request.query.foo)\n\nInstead you can write this::\n\n import safeint\n\n\n foo = safe.int(bottle.request.query.foo) \n\nsafe.int also has some syntactic sugar to save time when enforcing bounds. Instead of writing this::\n\n import safeint\n\n\n foo = safeint.int(bottle.request.query.foo)\n if foo > high:\n raise ValueError(...) \n elif foo < low:\n raise ValueError(...) \n\n\nyou can just write this::\n\n import safeint\n\n\n foo = safeint.int(bottle.request.query.foo, low=low, high=high)\n\n\nDevelopment\n-----------\n\nBug reports and pull requests welcome!\n\n\nAcknowledgments\n---------------\n\nPeloton_ for supporting open source!\n\n.. _Peloton: https://www.pelotoncycle.com/\n\nDan Sokolsky and Adam DePrince for implementing this solution!", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/pelotoncycle/safeint", "keywords": "int development security", "license": "MIT", "maintainer": "", "maintainer_email": "", "name": "safeint", "package_url": "https://pypi.org/project/safeint/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/safeint/", "project_urls": { "Homepage": "https://github.com/pelotoncycle/safeint" }, "release_url": "https://pypi.org/project/safeint/0.0.4/", "requires_dist": [ "six", "check-manifest; extra == 'dev'", "coverage; extra == 'test'", "flake8; extra == 'test'", "pytest; extra == 'test'", "pytest-cov; extra == 'test'" ], "requires_python": "", "summary": "Create an integer within a range.", "version": "0.0.4" }, "last_serial": 2143805, "releases": { "0.0.1": [ { "comment_text": "", "digests": { "md5": "9b851066d50063ce580dbb0ed56daa68", "sha256": "35f52841495b58b9b6848f1f3e9f6d020007509894039f7865eddf526b81ffd2" }, "downloads": -1, "filename": "safeint-0.0.1-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "9b851066d50063ce580dbb0ed56daa68", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 5485, "upload_time": "2016-05-25T15:49:27", "url": "https://files.pythonhosted.org/packages/4b/bd/2f965524cd126a0069be9e2771ed65a8420ce0145ad60dd4d74ddd578d42/safeint-0.0.1-py2.py3-none-any.whl" } ], "0.0.2": [ { "comment_text": "", "digests": { "md5": "de83bebbfdd2c9436189be4bf03d211c", "sha256": "2d81ff46ce2f8c63d7bacb5a91929374c714dc71e627a419956151aa8e95e68a" }, "downloads": -1, "filename": "safeint-0.0.2-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "de83bebbfdd2c9436189be4bf03d211c", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 5476, "upload_time": "2016-05-25T16:00:41", "url": "https://files.pythonhosted.org/packages/5d/5b/a2040a601b60dbb46f0e38ec9b36444aa23c4b75332f9e3590ba8ab4095e/safeint-0.0.2-py2.py3-none-any.whl" } ], "0.0.3": [ { "comment_text": "", "digests": { "md5": "65e388a93dc2981fc3a056c5714d80ad", "sha256": "16049dea304405bf03883245e61d7b97650e7fca8f4b48dd69508c7a04006bbf" }, "downloads": -1, "filename": "safeint-0.0.3-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "65e388a93dc2981fc3a056c5714d80ad", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 4885, "upload_time": "2016-05-25T17:08:06", "url": "https://files.pythonhosted.org/packages/a0/f6/bcc759a4555cee0d8e8fd00217eb20887cbf3e8d1e25f69085313f35bb3f/safeint-0.0.3-py2.py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "6b2edc5106f0fb3e02c642d53cfed1e0", "sha256": "f7a7e739902bffbebf07a07aa7f4541fad9c6ca109d0f6adc878d2f6f06eeed0" }, "downloads": -1, "filename": "safeint-0.0.3.tar.gz", "has_sig": false, "md5_digest": "6b2edc5106f0fb3e02c642d53cfed1e0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 3804, "upload_time": "2016-05-25T17:08:31", "url": "https://files.pythonhosted.org/packages/7c/e2/ac5ad3ceecb16b4a173541ff062fa1864652b74c6d7019c7581c56319d2d/safeint-0.0.3.tar.gz" } ], "0.0.4": [ { "comment_text": "", "digests": { "md5": "4541ecc4f59f97bde742189a2c4e3ee0", "sha256": "8496c8d9c32dd9fdc78b480529d6dd04b9ddd1a4e9cebafc2678a917d067316e" }, "downloads": -1, "filename": "safeint-0.0.4-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "4541ecc4f59f97bde742189a2c4e3ee0", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 4886, "upload_time": "2016-06-01T00:34:55", "url": "https://files.pythonhosted.org/packages/30/8c/b6692d64395af764c4b058e9bfd863256d8778691a2ba815f22a9aef48df/safeint-0.0.4-py2.py3-none-any.whl" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "4541ecc4f59f97bde742189a2c4e3ee0", "sha256": "8496c8d9c32dd9fdc78b480529d6dd04b9ddd1a4e9cebafc2678a917d067316e" }, "downloads": -1, "filename": "safeint-0.0.4-py2.py3-none-any.whl", "has_sig": false, "md5_digest": "4541ecc4f59f97bde742189a2c4e3ee0", "packagetype": "bdist_wheel", "python_version": "py2.py3", "requires_python": null, "size": 4886, "upload_time": "2016-06-01T00:34:55", "url": "https://files.pythonhosted.org/packages/30/8c/b6692d64395af764c4b058e9bfd863256d8778691a2ba815f22a9aef48df/safeint-0.0.4-py2.py3-none-any.whl" } ] }