Skip to content
Open
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
python2.7 \
python3-pip \
python3.8 \
rpm2cpio \
unrar \
unzip \
wget \
Expand Down
33 changes: 25 additions & 8 deletions dtrx/dtrx.py
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ class BaseExtractor(object):
"br": ["br", "--decompress"],
}
name_checker = DirectoryChecker
noprompt_value = ""

def __init__(self, filename, encoding):
if encoding and (encoding not in self.decoders):
Expand Down Expand Up @@ -619,6 +620,9 @@ def extract_archive(self):
# that will be replaced here
extract_fmt_args = {
"OUTPUT_FILE": os.path.splitext(os.path.basename(self.filename))[0],
# if we are in "batch" (--noninteractive) mode, the extractor might
# have extra fields that should be included
"NOPROMPT_FIELD": self.noprompt_value if self.ignore_pw else "",
}
formatted_extract_commands = [
x.format(**extract_fmt_args) for x in self.extract_command
Expand All @@ -634,8 +638,9 @@ def get_filenames(self):

class ZipExtractor(NoPipeExtractor):
file_type = "Zip file"
extract_command = ["unzip", "-q"]
extract_command = ["unzip", "-q", "{NOPROMPT_FIELD}"]
list_command = ["zipinfo", "-1"]
noprompt_value = "-o"

def is_fatal_error(self, status):
return (status or 0) > 1
Expand Down Expand Up @@ -685,9 +690,10 @@ def get_filenames(self):

class SevenExtractor(NoPipeExtractor):
file_type = "7z file"
extract_command = ["7z", "x"]
extract_command = ["7z", "x", "{NOPROMPT_FIELD}"]
list_command = ["7z", "l"]
border_re = re.compile("^[- ]+$")
noprompt_value = "-y"

def get_filenames(self):
fn_index = None
Expand All @@ -707,11 +713,18 @@ def timeout_check(self, pipe):

self.stderr += "".join(errs)

# pass through the password prompt, if 7z sent one
if errs and "password" in errs[-1]:
sys.stdout.write("\n" + errs[-1])
sys.stdout.flush()
self.pw_prompted = True
# handle some common 7z interactive prompts
if errs:
# pass through the password prompt, if 7z sent one
if "password" in errs[-1]:
sys.stdout.write("\n" + errs[-1])
sys.stdout.flush()
self.pw_prompted = True
elif "replace the existing file" in self.stderr:
# junk archive with duplicate contents. just crash out.
raise RuntimeError(
"Error, duplicate entries in archive:\n" + "".join(self.stderr)
)


class ZstandardExtractor(NoPipeExtractor):
Expand Down Expand Up @@ -1617,7 +1630,11 @@ def parse_options(self, arguments):
dest="batch",
action="store_true",
default=False,
help="don't ask how to handle special cases",
help=(
"don't ask how to handle special cases. note: this option can be"
" dangerous! it sets the extraction provider to overwrite duplicate"
" files without prompting"
),
)
parser.add_option(
"-o",
Expand Down
Binary file added tests/test.jar
Binary file not shown.
Binary file added tests/test.rpm
Binary file not shown.
21 changes: 21 additions & 0 deletions tests/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -908,3 +908,24 @@
zip
zst
zstd

- name: rpm
filenames: test.rpm
baseline: |
mkdir test
cd test
rpm2cpio ../$1 | cpio -i --make-directories --quiet --no-absolute-filenames

- name: jar
filenames: test.jar
baseline: |
mkdir test
cd test
rpm2cpio ../$1 | cpio -i --make-directories --quiet --no-absolute-filenames

- name: duplicate-overwrite
filenames: test-1.23.zip
baseline: |
mkdir test-1.23
cd test-1.23
unzip -q ../$1
12 changes: 12 additions & 0 deletions tools/jar_duplicate_entries.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"""
hacky script to insert duplicate entries to a .jar file
"""

import zipfile

# First run these commands
# $ echo hello > hello.txt
# $ jar --create --file test.jar hello.txt

with zipfile.ZipFile("test.jar", "a") as zf:
zf.write("hello.txt")