Skip to content

Commit

Permalink
New version for skipPos, major fix to Python redundancy check
Browse files Browse the repository at this point in the history
  • Loading branch information
agroce committed Mar 9, 2024
1 parent ae68084 commit f1d9bc9
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 12 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setup(
name='universalmutator',
version='1.1.8',
version='1.1.9',
description='Universal regexp-based mutation tool',
long_description_content_type="text/markdown",
long_description=open('README.md').read(),
Expand Down
37 changes: 26 additions & 11 deletions universalmutator/python_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import os
import sys
import py_compile
import uuid


def buildCode(c):
Expand All @@ -28,19 +29,33 @@ def buildCode(c):


def getPythonCode(fname):
# Courtesy of Ned Batchelder, just get the code object from the .pyc file
# from https://stackoverflow.com/questions/32562163/how-can-i-understand-a-pyc-file-content
header_sizes = [
# (size, first version this applies to)
# pyc files were introduced in 0.9.2 way, way back in June 1991.
(8, (0, 9, 2)), # 2 bytes magic number, \r\n, 4 bytes UNIX timestamp
(12, (3, 6)), # added 4 bytes file size
# bytes 4-8 are flags, meaning of 9-16 depends on what flags are set
# bit 0 not set: 9-12 timestamp, 13-16 file size
# bit 0 set: 9-16 file hash (SipHash-2-4, k0 = 4 bytes of the file, k1 = 0)
(16, (3, 7)), # inserted 4 bytes bit flag field at 4-8
# future version may add more bytes still, at which point we can extend
# this table. It is correct for Python versions up to 3.9
]
header_size = next(s for s, v in reversed(header_sizes) if sys.version_info >= v)

with open(fname, "rb") as f:
f.read(4)
f.read(4)
if sys.version_info >= (3, 3):
f.read(4)
metadata = f.read(header_size) # first header_size bytes are metadata
try:
code = marshal.load(f)
except (EOFError, TypeError, ValueError):
with open(fname, "rb") as fRetry:
fRetry.read(16)
code = marshal.load(fRetry)
return buildCode(code)
code = marshal.load(f) # rest is a marshalled code object
except:
print("WARNING: UNABLE TO MARSHAL CODE FROM PYC FILE!")
return(uuid.uuid4())
if ("code" not in str(type(code))):
print("WARNING: INVALID CODE OBJECT READ FROM PYC FILE!")
return(uuid.uuid4())
b = buildCode(code)
return b


def handler(tmpMutantName, mutant, sourceFile, uniqueMutants):
Expand Down
2 changes: 2 additions & 0 deletions universalmutator/static/python.rules
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,5 @@ True ==> False
'.+' ==> ''

@.* ==>

# ==> SKIP_MUTATING_REST

0 comments on commit f1d9bc9

Please sign in to comment.