mirror of
https://github.com/borgbackup/borg.git
synced 2025-02-25 07:23:28 +00:00
add generic text and comment validator
This commit is contained in:
parent
ebff12ad41
commit
99c6afbc61
3 changed files with 45 additions and 2 deletions
|
@ -26,7 +26,7 @@
|
|||
from .parseformat import format_line, replace_placeholders, PlaceholderError
|
||||
from .parseformat import SortBySpec, NameSpec
|
||||
from .parseformat import format_archive, parse_stringified_list, clean_lines
|
||||
from .parseformat import Location, location_validator, archivename_validator
|
||||
from .parseformat import Location, location_validator, archivename_validator, comment_validator, text_validator
|
||||
from .parseformat import BaseFormatter, ArchiveFormatter, ItemFormatter, file_status
|
||||
from .parseformat import swidth_slice, ellipsis_truncate
|
||||
from .parseformat import BorgJsonEncoder, basic_json_data, json_print, json_dump, prepare_dump_dict
|
||||
|
|
|
@ -573,6 +573,26 @@ def validator(text):
|
|||
return validator
|
||||
|
||||
|
||||
def text_validator(*, name, max_length, invalid_ctrl_chars="\0"):
|
||||
def validator(text):
|
||||
assert isinstance(text, str)
|
||||
if not (len(text) <= max_length):
|
||||
raise argparse.ArgumentTypeError(f'Invalid {name}: "{text}" [length <= {max_length}]')
|
||||
if re.search(f"[{re.escape(invalid_ctrl_chars)}]", text):
|
||||
raise argparse.ArgumentTypeError(f'Invalid {name}: "{text}" [invalid control chars detected]')
|
||||
try:
|
||||
text.encode("utf-8", errors="strict")
|
||||
except UnicodeEncodeError:
|
||||
# looks like text contains surrogate-escapes
|
||||
raise argparse.ArgumentTypeError(f'Invalid {name}: "{text}" [contains non-unicode characters]')
|
||||
return text
|
||||
|
||||
return validator
|
||||
|
||||
|
||||
comment_validator = text_validator(name="comment", max_length=10000)
|
||||
|
||||
|
||||
class BaseFormatter:
|
||||
FIXED_KEYS = {
|
||||
# Formatting aids
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
from ..helpers import yes, TRUISH, FALSISH, DEFAULTISH
|
||||
from ..helpers import StableDict, bin_to_hex
|
||||
from ..helpers import parse_timestamp, ChunkIteratorFileWrapper, ChunkerParams
|
||||
from ..helpers import archivename_validator
|
||||
from ..helpers import archivename_validator, text_validator
|
||||
from ..helpers import ProgressIndicatorPercent, ProgressIndicatorEndless
|
||||
from ..helpers import swidth_slice
|
||||
from ..helpers import chunkit
|
||||
|
@ -290,6 +290,29 @@ def test_archivename_invalid(name):
|
|||
av(name)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("text", ["", "single line", "multi\nline\ncomment"])
|
||||
def test_text_ok(text):
|
||||
tv = text_validator(max_length=100, name="name")
|
||||
tv(text) # must not raise an exception
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"text",
|
||||
[
|
||||
"x" * 101, # too long
|
||||
# invalid chars:
|
||||
"foo\0bar",
|
||||
# contains surrogate-escapes
|
||||
"foo\udc80bar",
|
||||
"foo\udcffbar",
|
||||
],
|
||||
)
|
||||
def test_text_invalid(text):
|
||||
tv = text_validator(max_length=100, name="name")
|
||||
with pytest.raises(ArgumentTypeError):
|
||||
tv(text)
|
||||
|
||||
|
||||
class FormatTimedeltaTestCase(BaseTestCase):
|
||||
def test(self):
|
||||
t0 = datetime(2001, 1, 1, 10, 20, 3, 0)
|
||||
|
|
Loading…
Reference in a new issue