|
1 | 1 | import logging |
2 | 2 | import re |
3 | 3 | from pathlib import Path |
4 | | -from typing import TYPE_CHECKING, Callable, List, Optional |
| 4 | +from typing import TYPE_CHECKING, Callable |
5 | 5 |
|
6 | 6 | if TYPE_CHECKING: |
7 | 7 | from io import BytesIO |
@@ -162,7 +162,7 @@ def _process_macro_node_inline( |
162 | 162 | parent: NodeItem | None, |
163 | 163 | formatting: Formatting | None, |
164 | 164 | text_label: DocItemLabel | None, |
165 | | - text_buffer: List[str], |
| 165 | + text_buffer: list[str], |
166 | 166 | flush_fn: Callable[[], None], |
167 | 167 | following_nodes=None, |
168 | 168 | ) -> int: |
@@ -307,7 +307,19 @@ def _process_macro( # noqa: C901 |
307 | 307 | image = None |
308 | 308 | try: |
309 | 309 | if isinstance(self.path_or_stream, Path): |
| 310 | + base_dir = self.path_or_stream.parent.resolve() |
310 | 311 | img_full_path = self.path_or_stream.parent / img_path |
| 312 | + try: |
| 313 | + if not img_full_path.resolve().is_relative_to(base_dir): |
| 314 | + _log.warning( |
| 315 | + f"Path traversal attempt blocked for image: {img_path}" |
| 316 | + ) |
| 317 | + raise ValueError("Path traversal not allowed") |
| 318 | + except ValueError: |
| 319 | + _log.warning( |
| 320 | + f"Invalid path for image (different drive or traversal): {img_path}" |
| 321 | + ) |
| 322 | + raise |
311 | 323 | if img_full_path.exists(): |
312 | 324 | suffix = img_full_path.suffix.lower() |
313 | 325 | if suffix == ".pdf": |
@@ -353,9 +365,23 @@ def _process_macro( # noqa: C901 |
353 | 365 |
|
354 | 366 | filepath = self._extract_macro_arg(node) |
355 | 367 | if filepath and isinstance(self.path_or_stream, Path): |
| 368 | + base_dir = self.path_or_stream.parent.resolve() |
356 | 369 | input_path = self.path_or_stream.parent / filepath |
357 | 370 | if not input_path.suffix: |
358 | 371 | input_path = input_path.with_suffix(".tex") |
| 372 | + |
| 373 | + try: |
| 374 | + if not input_path.resolve().is_relative_to(base_dir): |
| 375 | + _log.warning( |
| 376 | + f"Path traversal attempt blocked for input file: {filepath}" |
| 377 | + ) |
| 378 | + return |
| 379 | + except ValueError: |
| 380 | + _log.warning( |
| 381 | + f"Invalid path for input file (different drive or traversal): {filepath}" |
| 382 | + ) |
| 383 | + return |
| 384 | + |
359 | 385 | resolved = str(input_path.resolve()) |
360 | 386 | if resolved in self._input_stack: |
361 | 387 | _log.warning(f"Circular \\input detected: {filepath}") |
|
0 commit comments