Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change hexdump_iter to not rely on the length of its input file #850

Merged
merged 3 commits into from
Jan 12, 2017
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 20 additions & 23 deletions pwnlib/util/fiddling.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
from ..context import context
from ..log import getLogger
from ..term import text
from .cyclic import cyclic
from .cyclic import de_bruijn
from .cyclic import cyclic_find

log = getLogger(__name__)
Expand Down Expand Up @@ -560,13 +560,15 @@ def _hexiichar(c):
}

cyclic_pregen = ''
de_bruijn_gen = de_bruijn()

def sequential_lines(a,b):
return (a+b) in cyclic_pregen

def update_cyclic_pregenerated(size):
global cyclic_pregen
cyclic_pregen = cyclic(size)
while size > len(cyclic_pregen):
cyclic_pregen += de_bruijn_gen.next()

def hexdump_iter(fd, width=16, skip=True, hexii=False, begin=0, style=None,
highlight=None, cyclic=False):
Expand Down Expand Up @@ -609,23 +611,6 @@ def hexdump_iter(fd, width=16, skip=True, hexii=False, begin=0, style=None,
spacer = ' '
marker = (style.get('marker') or (lambda s:s))('│')

# Total length of the input stream
total = 0

if hasattr(fd, 'len'):
total = fd.len
else:
# Save the current file offset
cur = fd.tell()

# Determine the total size of the file
fd.seek(0, os.SEEK_END)
total = fd.tell() - cur

# Restore the file offset, and
fd.seek(cur or 0, os.SEEK_SET)


if hexii:
column_sep = ''
line_fmt = '%%(offset)08x %%(hexbytes)-%is│' % (len(column_sep)+(width*byte_width))
Expand All @@ -645,17 +630,29 @@ def style_byte(b):
return hbyte, abyte
cache = [style_byte(chr(b)) for b in range(256)]

if cyclic:
update_cyclic_pregenerated(total)

numb = 0
while True:
offset = begin + numb
chunk = fd.read(width)

# If a tube is passed in as fd, it will raise EOFError when it runs
# out of data, unlike a file or StringIO object, which return an empty
# string.
try:
chunk = fd.read(width)
except EOFError:
chunk = ''

# We have run out of data, exit the loop
if chunk == '':
break

# Advance the cursor by the number of bytes we actually read
numb += len(chunk)

# Update the cyclic pattern in case
if cyclic:
update_cyclic_pregenerated(numb)

# If this chunk is the same as the last unique chunk,
# use a '*' instead.
if skip and last_unique:
Expand Down