Skip to content

Commit 3b64fba

Browse files
philippottofm3
andauthored
Guard against non-ascii characters in shell commands (#893)
* subclass ArgumentParser so that non-ascii characters are guarded against * fix super call * format * Update wkcuber/wkcuber/_internal/utils.py Co-authored-by: Florian M <[email protected]> * add comment * also allow --allow-non-ascii even if no ascii chars exist in argv --------- Co-authored-by: Florian M <[email protected]>
1 parent 82e1e0e commit 3b64fba

16 files changed

+68
-17
lines changed

wkcuber/wkcuber/_internal/utils.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1+
import sys
2+
import re
3+
from argparse import ArgumentParser, Namespace
14
from collections import namedtuple
25
from glob import iglob
36
from logging import getLogger
47
from math import ceil, floor
58
from os import environ
6-
from typing import Generator, Sequence, Tuple, Union
9+
from typing import Generator, Sequence, Tuple, Union, Optional
710

811
import numpy as np
912
import wkw
@@ -65,6 +68,34 @@ def parse_padding(padding_str: str) -> Tuple[int, ...]:
6568
raise argparse.ArgumentTypeError("The padding could not be parsed") from e
6669

6770

71+
class AsciiArgumentParser(ArgumentParser):
72+
"""
73+
This class is a lightweight wrapper around ArgumentParser and checks
74+
that the shell command doesn't contain non-ascii characters since these
75+
can easily disturb the argument parsing.
76+
77+
If non-ascii characters are found, an error is raised. This behavior
78+
can be disabled by passing --allow-non-ascii on the command line.
79+
"""
80+
81+
IGNORE_FLAG = "--allow-non-ascii"
82+
83+
def parse_args(self, args: Optional[Sequence[str]] = None, namespace: Optional[Namespace] = None) -> Any: # type: ignore
84+
if args is None:
85+
args = sys.argv[1:]
86+
87+
# Search for non-ascii codes (ASCII itself spans 0-127 or 0x00 to 0x7F).
88+
results = re.findall(r"[^\x00-\x7F]", " ".join(args))
89+
if len(results) > 0:
90+
if not self.IGNORE_FLAG in args:
91+
raise ValueError(
92+
f"The shell command contains non-ascii characters. Please remove them to avoid unintended effects. If you need them, pass {self.IGNORE_FLAG} to suppress this error. The special characters are: {results}"
93+
)
94+
95+
args = [el for el in args if el != self.IGNORE_FLAG]
96+
return super().parse_args(args, namespace)
97+
98+
6899
def open_knossos(info: KnossosDatasetInfo) -> KnossosDataset:
69100
return KnossosDataset.open(info.dataset_path, np.dtype(info.dtype))
70101

wkcuber/wkcuber/check_equality.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from webknossos import Dataset, View
88

99
from ._internal.utils import (
10+
AsciiArgumentParser,
1011
add_distribution_flags,
1112
add_verbose_flag,
1213
parse_path,
@@ -17,7 +18,7 @@
1718

1819

1920
def create_parser() -> ArgumentParser:
20-
parser = ArgumentParser()
21+
parser = AsciiArgumentParser()
2122

2223
parser.add_argument(
2324
"source_path", help="Path to input WKW dataset", type=parse_path

wkcuber/wkcuber/compress.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from webknossos.utils import rmtree
88

99
from ._internal.utils import (
10+
AsciiArgumentParser,
1011
add_distribution_flags,
1112
add_verbose_flag,
1213
parse_path,
@@ -18,7 +19,7 @@
1819

1920

2021
def create_parser() -> ArgumentParser:
21-
parser = ArgumentParser()
22+
parser = AsciiArgumentParser()
2223

2324
parser.add_argument(
2425
"source_path",

wkcuber/wkcuber/convert_knossos.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from ._internal.knossos import CUBE_EDGE_LEN
1212
from ._internal.utils import (
13+
AsciiArgumentParser,
1314
KnossosDatasetInfo,
1415
add_data_format_flags,
1516
add_distribution_flags,
@@ -24,7 +25,7 @@
2425

2526

2627
def create_parser() -> ArgumentParser:
27-
parser = ArgumentParser()
28+
parser = AsciiArgumentParser()
2829

2930
parser.add_argument(
3031
"source_path",

wkcuber/wkcuber/convert_nifti.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from webknossos.utils import time_start, time_stop
1212

1313
from ._internal.utils import (
14+
AsciiArgumentParser,
1415
add_data_format_flags,
1516
add_verbose_flag,
1617
add_voxel_size_flag,
@@ -23,7 +24,7 @@
2324

2425

2526
def create_parser() -> ArgumentParser:
26-
parser = ArgumentParser()
27+
parser = AsciiArgumentParser()
2728

2829
parser.add_argument(
2930
"source_path",

wkcuber/wkcuber/convert_raw.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
)
1616

1717
from ._internal.utils import (
18+
AsciiArgumentParser,
1819
add_data_format_flags,
1920
add_distribution_flags,
2021
add_interpolation_flag,
@@ -47,7 +48,7 @@ def parse_flip_axes(flip_axes: str) -> Tuple[int, ...]:
4748

4849

4950
def create_parser() -> argparse.ArgumentParser:
50-
parser = argparse.ArgumentParser()
51+
parser = AsciiArgumentParser()
5152

5253
parser.add_argument(
5354
"source_path",

wkcuber/wkcuber/convert_zarr.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from webknossos.utils import get_executor_for_args, wait_and_ensure_success
2222

2323
from ._internal.utils import (
24+
AsciiArgumentParser,
2425
add_data_format_flags,
2526
add_distribution_flags,
2627
add_interpolation_flag,
@@ -46,7 +47,7 @@ def parse_flip_axes(flip_axes: str) -> Tuple[int, ...]:
4647

4748

4849
def create_parser() -> argparse.ArgumentParser:
49-
parser = argparse.ArgumentParser()
50+
parser = AsciiArgumentParser()
5051

5152
parser.add_argument(
5253
"source_path",

wkcuber/wkcuber/converter.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99

1010
from ._internal.image_readers import image_reader
1111
from ._internal.utils import (
12+
AsciiArgumentParser,
1213
add_data_format_flags,
1314
add_verbose_flag,
1415
add_voxel_size_flag,
@@ -32,7 +33,7 @@
3233

3334

3435
def create_parser() -> ArgumentParser:
35-
parser = ArgumentParser(
36+
parser = AsciiArgumentParser(
3637
epilog="If you want to pass more specific config values, please use the individual converters. See the readme for a complete overview."
3738
)
3839

wkcuber/wkcuber/cubing.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
from ._internal.image_readers import image_reader
3131
from ._internal.utils import (
32+
AsciiArgumentParser,
3233
add_batch_size_flag,
3334
add_data_format_flags,
3435
add_distribution_flags,
@@ -46,7 +47,7 @@
4647

4748

4849
def create_parser() -> ArgumentParser:
49-
parser = ArgumentParser()
50+
parser = AsciiArgumentParser()
5051

5152
parser.add_argument(
5253
"source_path", help="Directory containing the input images.", type=Path

wkcuber/wkcuber/downsampling.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from webknossos.utils import get_executor_for_args
77

88
from ._internal.utils import (
9+
AsciiArgumentParser,
910
add_distribution_flags,
1011
add_interpolation_flag,
1112
add_isotropic_flag,
@@ -18,7 +19,7 @@
1819

1920

2021
def create_parser() -> ArgumentParser:
21-
parser = ArgumentParser()
22+
parser = AsciiArgumentParser()
2223

2324
parser.add_argument(
2425
"path", help="Directory containing the dataset.", type=parse_path

0 commit comments

Comments
 (0)