Skip to content

Commit 096eb49

Browse files
committed
fix(extractor): stronger implementation of fix_extracted_directory.
1. recursive walking We re-implemented fix_extracted_directory using os.listdir(). We do not rely on os.walk because we need to fix the permissions recursively in order to gain visibility into child directories. If we were to use os.walk() on a directory containing directories on which we don't have read permissions would mean we would not fix the content of those directories. 2. handling ENAMETOOLONG fix_extracted_directory now handles ENAMETOOLONG exception triggered on symlinks with overly long target names. When that happens, we skip over the file. 3. handling concurrent deletion Someone (or something) can delete an object (file, directory, link, ...) from the extraction directory as we are walking through it. We're also handling such cases now so we don't raise FileNotFoundError.
1 parent 993ecaa commit 096eb49

File tree

9 files changed

+27
-5
lines changed

9 files changed

+27
-5
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version https://git-lfs.github.com/spec/v1
2+
oid sha256:f5db6b45d5ce63976001aba342e9928dff1f75ee2ce3033269ca2fcaf5b9f80a
3+
size 1048576
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
foo
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaҾ
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

tests/integration/filesystem/extfs/__output__/f_badsymlinks.img_extract/lost+found/.gitkeep

Whitespace-only changes.

unblob/extractor.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
"""File extraction related functions."""
2+
import errno
23
import os
34
from pathlib import Path
45

@@ -91,12 +92,24 @@ def fix_symlink(path: Path, outdir: Path, task_result: TaskResult) -> Path:
9192

9293

9394
def fix_extracted_directory(outdir: Path, task_result: TaskResult):
95+
def _fix_extracted_directory(directory: Path):
96+
if not directory.exists():
97+
return
98+
for path in (directory / p for p in os.listdir(directory)):
99+
try:
100+
fix_permission(path)
101+
if path.is_symlink():
102+
fix_symlink(path, outdir, task_result)
103+
continue
104+
if path.is_dir():
105+
_fix_extracted_directory(path)
106+
except OSError as e:
107+
if e.errno == errno.ENAMETOOLONG:
108+
continue
109+
raise e from None
110+
94111
fix_permission(outdir)
95-
for path in outdir.rglob("*"):
96-
if path.is_symlink():
97-
fix_symlink(path, outdir, task_result)
98-
else:
99-
fix_permission(path)
112+
_fix_extracted_directory(outdir)
100113

101114

102115
def carve_unknown_chunk(extract_dir: Path, file: File, chunk: UnknownChunk) -> Path:

0 commit comments

Comments
 (0)