1
0
Fork 0
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:
Thomas Waldmann 2022-12-12 18:01:07 +01:00
parent ebff12ad41
commit 99c6afbc61
No known key found for this signature in database
GPG key ID: 243ACFA951F78E01
3 changed files with 45 additions and 2 deletions

View file

@ -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

View file

@ -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

View file

@ -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)