Skip to content

Instantly share code, notes, and snippets.

@boronine
Last active February 22, 2018 15:42
Show Gist options
  • Save boronine/e5fe9198374d9a9b6270470ed98e4697 to your computer and use it in GitHub Desktop.
Save boronine/e5fe9198374d9a9b6270470ed98e4697 to your computer and use it in GitHub Desktop.
Test maximum shebang length
import os
import stat
import tempfile
import subprocess
shebang_prefix = '#!/usr/bin/env DUMMY=x'
shebang_suffix = ' python\n'
shebang_length_min = len(shebang_prefix) + len(shebang_suffix)
TEST_FILE_HANDLE, TEST_FILE = tempfile.mkstemp('.py')
def executable(shebang_length):
assert shebang_length >= shebang_length_min
num_extra_chars = shebang_length - shebang_length_min
extra_chars = 'x' * num_extra_chars
shebang = shebang_prefix + extra_chars + shebang_suffix
return shebang + 'import sys; sys.exit(7)\n'
def shebang_works(shebang_length):
with open(TEST_FILE, 'w') as f:
f.write(executable(shebang_length))
# Make executable
st = os.stat(TEST_FILE)
os.chmod(TEST_FILE, st.st_mode | stat.S_IEXEC)
os.close(TEST_FILE_HANDLE)
try:
subprocess.check_output([TEST_FILE])
except subprocess.CalledProcessError as e:
if e.returncode == 7:
return True
except OSError as err:
if err.args == (8, 'Exec format error'):
# This OSError means shebang is bad
return False
else:
# Not sure what this one means
raise err
return False
def main():
# shebang works when (<=) bound_lower and does not work when (>=) bound_upper
bound_lower = length_test = 32
bound_upper = None
print('finding upper bound')
while bound_upper is None:
if shebang_works(length_test):
bound_lower = length_test
length_test *= 2
else:
bound_upper = length_test
print('searching cutoff')
while bound_upper - bound_lower > 1:
length_test = bound_lower + (bound_upper - bound_lower) // 2
if shebang_works(length_test):
bound_lower = length_test
else:
bound_upper = length_test
print('maximum shebang length (including newline)')
print(bound_lower)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment