Compare commits

...
5 Commits
Author SHA1 Message Date
Mathias Svensson 8b07fe12e6 Release 3.0.2 2016-09-06 11:33:46 -10:00
Mathias Svensson 684e9f6791 Changed util.fiddling.hexdump_iter to take a file object instead of a string. This massively speeds up phd <file> | less for huge files. (#695) (#725) 2016-09-06 11:30:51 -10:00
Mathias Svensson 8d15fceb92 Backported #720. (#722)
The backport only includes the changes in pwnlib/update.py, not the
stuff in pwnlib/commandline/
2016-09-06 10:06:45 -10:00
Evan Grim 24dfaa0ff7 Fix typos (#702) 2016-08-24 20:03:37 -07:00
Mathias Svensson 6415367f15 Even more documentation (#678) 2016-08-22 15:16:02 -07:00
9 changed files with 90 additions and 44 deletions

No files matched your search

+6
View File
@@ -3,6 +3,12 @@
This changelog only includes added major features and changes. Bugfixes and
minor changes are omitted.
## 3.0.2 (September 6 2016)
- Cherry-pick #695, as this was a regression-fix.
- Added a fix for the update checker, as it would suggest prereleases as updates to stable releases.
- Various documentation fixes.
## 3.0.1 (August 20 2016)
A small bugfix release. There were a lot of references to the `master`-branch, however after 3.0.0 we use the names `stable`, `beta` and `dev` for our branches.
+1
View File
@@ -31,6 +31,7 @@ Alternatively you can get early access to the beta release if you want to help
file bugs or simple get newer features:
.. code-block:: bash
$ pip install --upgrade --pre pwntools
+1 -3
View File
@@ -83,8 +83,6 @@ def main():
else:
infile.seek(skip, os.SEEK_CUR)
data = infile.read(count)
hl = []
if args.highlight:
for hs in args.highlight:
@@ -92,7 +90,7 @@ def main():
hl.append(asint(h))
try:
for line in hexdump_iter(data, width, highlight = hl, begin = offset + skip):
for line in hexdump_iter(infile, width, highlight = hl, begin = offset + skip):
print line
except (KeyboardInterrupt, IOError):
pass
+1 -1
View File
@@ -1202,7 +1202,7 @@ if 'ANDROID_ADB_SERVER_PORT' in os.environ:
def LocalContext(function):
"""
Wraps the specied function on a context.local() block, using kwargs.
Wraps the specified function on a context.local() block, using kwargs.
Example:
+10 -10
View File
@@ -144,7 +144,7 @@ class tube(Timeout, Logger):
def _recv(self, numb = 4096, timeout = default):
"""_recv(numb = 4096, timeout = default) -> str
Recieves one chunk of from the internal buffer or from the OS if the
Receives one chunk of from the internal buffer or from the OS if the
buffer is empty.
"""
data = ''
@@ -198,7 +198,7 @@ class tube(Timeout, Logger):
def recvn(self, numb, timeout = default):
"""recvn(numb, timeout = default) -> str
Recieves exactly `n` bytes.
Receives exactly `n` bytes.
If the request is not satisfied before ``timeout`` seconds pass,
all data is buffered and an empty string (``''``) is returned.
@@ -246,7 +246,7 @@ class tube(Timeout, Logger):
def recvuntil(self, delims, drop=False, timeout = default):
"""recvuntil(delims, timeout = default) -> str
Recieve data until one of `delims` is encountered.
Receive data until one of `delims` is encountered.
If the request is not satisfied before ``timeout`` seconds pass,
all data is buffered and an empty string (``''``) is returned.
@@ -337,7 +337,7 @@ class tube(Timeout, Logger):
def recvlines(self, numlines=2**20, keepends = False, timeout = default):
r"""recvlines(numlines, keepends = False, timeout = default) -> str list
Recieve up to ``numlines`` lines.
Receive up to ``numlines`` lines.
A "line" is any sequence of bytes terminated by the byte sequence
set by :attr:`newline`, which defaults to ``'\n'``.
@@ -516,8 +516,8 @@ class tube(Timeout, Logger):
def recvline_startswith(self, delims, keepends = False, timeout = default):
r"""recvline_startswith(delims, keepends = False, timeout = default) -> str
Keep recieving lines until one is found that starts with one of
`delims`. Returns the last line recieved.
Keep receiving lines until one is found that starts with one of
`delims`. Returns the last line received.
If the request is not satisfied before ``timeout`` seconds pass,
all data is buffered and an empty string (``''``) is returned.
@@ -554,8 +554,8 @@ class tube(Timeout, Logger):
def recvline_endswith(self, delims, keepends = False, timeout = default):
r"""recvline_endswith(delims, keepends = False, timeout = default) -> str
Keep recieving lines until one is found that starts with one of
`delims`. Returns the last line recieved.
Keep receiving lines until one is found that starts with one of
`delims`. Returns the last line received.
If the request is not satisfied before ``timeout`` seconds pass,
all data is buffered and an empty string (``''``) is returned.
@@ -669,7 +669,7 @@ class tube(Timeout, Logger):
Receives data until EOF is reached.
"""
with self.waitfor('Recieving all data') as h:
with self.waitfor('Receiving all data') as h:
l = len(self.buffer)
with self.local(timeout):
try:
@@ -858,7 +858,7 @@ class tube(Timeout, Logger):
def clean_and_log(self, timeout = 0.05):
r"""clean_and_log(timeout = 0.05)
Works exactly as :meth:`pwnlib.tubes.tube.tube.clean`, but logs recieved
Works exactly as :meth:`pwnlib.tubes.tube.tube.clean`, but logs received
data with :meth:`pwnlib.self.info`.
Returns:
+20 -7
View File
@@ -19,16 +19,22 @@ package_name = 'pwntools'
package_repo = 'Gallopsled/pwntools'
update_freq = datetime.timedelta(days=7).total_seconds()
def available_on_github():
def available_on_github(prerelease=False):
"""Return True if an update is available on Github."""
url = 'https://api.github.com/repos/%s/tags' % package_repo
with context.quiet:
tags = json.loads(wget(url))
return max(map(pkg_resources.parse_version, [t['name'] for t in tags]))
def available_on_pypi():
versions = map(pkg_resources.parse_version, [t['name'] for t in tags])
if not prerelease:
versions = filter(lambda v: not v.is_prerelease, versions)
return max(versions)
def available_on_pypi(prerelease=False):
"""Return True if an update is available on PyPI."""
search_command = pip.commands.search.SearchCommand()
options, _ = search_command.parse_args([package_name])
@@ -36,7 +42,13 @@ def available_on_pypi():
for hit in pip.commands.search.transform_hits(pypi_hits):
if hit['name'] != 'pwntools':
continue
return max(map(pkg_resources.parse_version, hit['versions']))
versions = map(pkg_resources.parse_version, hit['versions'])
if not prerelease:
versions = filter(lambda v: not v.is_prerelease, versions)
return max(versions)
def cache_file():
"""Returns the path of the file used to cache update data, and ensures that it exists."""
@@ -61,17 +73,17 @@ def should_check():
return False
return time.time() > (last_check() + update_freq)
def perform_check():
def perform_check(prerelease=False):
"""Perform the update check, and report to the user."""
pypi = current_version
try:
pypi = available_on_pypi()
pypi = available_on_pypi(prerelease)
except:
log.warning("An issue occurred while checking PyPI")
github = current_version
try:
github = available_on_github()
github = available_on_github(prerelease)
except:
log.warning("An issue occurred while checking Github")
@@ -95,6 +107,7 @@ def perform_check():
log.info("A newer version of %s is available on %s (%s --> %s).\n" % (package_name, where, current_version, best) +
"Update with: $ %s" % command)
return command
def check_automatically():
if should_check():
+49 -21
View File
@@ -3,6 +3,7 @@ import base64
import random
import re
import string
import StringIO
from . import lists
from . import packing
@@ -487,7 +488,7 @@ def rol(n, k, word_size = None):
def ror(n, k, word_size = None):
"""A simple wrapper around :func:`rol`, which negates the values of `k`."""
return ror(n, -k, word_size)
return rol(n, -k, word_size)
def naf(n):
"""naf(int) -> int generator
@@ -566,15 +567,16 @@ def update_cyclic_pregenerated(size):
global cyclic_pregen
cyclic_pregen = cyclic(size)
def hexdump_iter(s, width = 16, skip = True, hexii = False, begin = 0,
style = None, highlight = None, cyclic=False):
def hexdump_iter(fd, width=16, skip=True, hexii=False, begin=0, style=None,
highlight=None, cyclic=False):
"""hexdump_iter(s, width = 16, skip = True, hexii = False, begin = 0,
style = {}, highlight = []) -> str generator
style = None, highlight = None, cyclic = False) -> str generator
Return a hexdump-dump of a string as a generator of lines.
Return a hexdump-dump of a string as a generator of lines. Unless you have
massive amounts of data you probably want to use :meth:`hexdump`.
Arguments:
s(str): The string to dump
fd(file): File object to dump. Use :meth:`StringIO.StringIO` or :meth:`hexdump` to dump a string.
width(int): The number of characters per line
skip(bool): Set to True, if repeated lines should be replaced by a "*"
hexii(bool): Set to True, if a hexii-dump should be returned instead of a hexdump.
@@ -584,7 +586,7 @@ def hexdump_iter(s, width = 16, skip = True, hexii = False, begin = 0,
cyclic(bool): Attempt to skip consecutive, unmodified cyclic lines
Returns:
A hexdump-dump in the form of a string.
A generator producing the hexdump-dump one line at a time.
"""
style = style or {}
highlight = highlight or []
@@ -628,16 +630,18 @@ def hexdump_iter(s, width = 16, skip = True, hexii = False, begin = 0,
if cyclic:
update_cyclic_pregenerated(len(s))
chunks = lists.group(width, s)
for line, chunk in enumerate(chunks):
numb = 0
while True:
offset = begin + numb
chunk = fd.read(width)
if chunk == '':
break
numb += len(chunk)
# If this chunk is the same as the last unique chunk,
# use a '*' instead.
if line != 0 \
and line != len(chunks)-1 \
and skip \
and (last_unique == chunk \
or (cyclic and sequential_lines(last_unique, chunk))):
if skip and \
(last_unique == chunk or \
(cyclic and sequential_lines(last_unique, chunk))):
last_unique = chunk
if not skipping:
yield '*'
@@ -648,8 +652,7 @@ def hexdump_iter(s, width = 16, skip = True, hexii = False, begin = 0,
last_unique = chunk
skipping = False
# Cenerate contents for line
offset = begin+line*width
# Generate contents for line
hexbytes = ''
printable = ''
for i, b in enumerate(chunk):
@@ -672,13 +675,38 @@ def hexdump_iter(s, width = 16, skip = True, hexii = False, begin = 0,
line = line_fmt % {'offset': offset, 'hexbytes': hexbytes, 'printable': printable}
yield line
line = "%08x" % (len(s) + begin)
line = "%08x" % (begin + numb)
yield line
def hexdump(s, width = 16, skip = True, hexii = False, begin = 0,
style = None, highlight = None, cyclic=False):
def hexdump(s, width=16, skip=True, hexii=False, begin=0,
style=None, highlight=None, cyclic=False):
"""hexdump(s, width = 16, skip = True, hexii = False, begin = 0,
style = None, highlight = None, cyclic = False) -> str generator
Return a hexdump-dump of a string.
Arguments:
s(str): The data to hexdump.
width(int): The number of characters per line
skip(bool): Set to True, if repeated lines should be replaced by a "*"
hexii(bool): Set to True, if a hexii-dump should be returned instead of a hexdump.
begin(int): Offset of the first byte to print in the left column
style(dict): Color scheme to use.
highlight(iterable): Byte values to highlight.
cyclic(bool): Attempt to skip consecutive, unmodified cyclic lines
Returns:
A hexdump-dump in the form of a string.
"""
s = packing.flat(s)
return '\n'.join(hexdump_iter(s, width, skip, hexii, begin, style, highlight, cyclic))
return '\n'.join(hexdump_iter(StringIO.StringIO(s),
width,
skip,
hexii,
begin,
style,
highlight,
cyclic))
def negate(value, width = None):
"""
+1 -1
View File
@@ -1 +1 @@
__version__ = '3.0.1'
__version__ = '3.0.2'
+1 -1
View File
@@ -59,7 +59,7 @@ if not os.path.exists(PythonH):
setup(
name = 'pwntools',
packages = find_packages(),
version = '3.0.1',
version = '3.0.2',
data_files = [('',
['LICENSE-pwntools.txt',
]),