PATH: do not accept empty strings, fixes #4221

This commit is contained in:
Thomas Waldmann 2024-01-02 19:17:55 +01:00
parent 1432f547fe
commit 73284db53f
No known key found for this signature in database
GPG Key ID: 243ACFA951F78E01
10 changed files with 26 additions and 16 deletions

View File

@ -16,7 +16,7 @@ from ..archive import FilesystemObjectProcessors, MetadataCollector, ChunksProce
from ..cache import Cache from ..cache import Cache
from ..constants import * # NOQA from ..constants import * # NOQA
from ..compress import CompressionSpec from ..compress import CompressionSpec
from ..helpers import comment_validator, ChunkerParams from ..helpers import comment_validator, ChunkerParams, PathSpec
from ..helpers import archivename_validator, FilesCacheMode from ..helpers import archivename_validator, FilesCacheMode
from ..helpers import eval_escapes from ..helpers import eval_escapes
from ..helpers import timestamp, archive_ts_now from ..helpers import timestamp, archive_ts_now
@ -937,4 +937,6 @@ class CreateMixIn:
) )
subparser.add_argument("name", metavar="NAME", type=archivename_validator, help="specify the archive name") subparser.add_argument("name", metavar="NAME", type=archivename_validator, help="specify the archive name")
subparser.add_argument("paths", metavar="PATH", nargs="*", type=str, action="extend", help="paths to archive") subparser.add_argument(
"paths", metavar="PATH", nargs="*", type=PathSpec, action="extend", help="paths to archive"
)

View File

@ -7,7 +7,7 @@ import os
from ._common import with_repository, with_archive, build_matcher, Highlander from ._common import with_repository, with_archive, build_matcher, Highlander
from ..archive import Archive from ..archive import Archive
from ..constants import * # NOQA from ..constants import * # NOQA
from ..helpers import BaseFormatter, DiffFormatter, archivename_validator, BorgJsonEncoder from ..helpers import BaseFormatter, DiffFormatter, archivename_validator, PathSpec, BorgJsonEncoder
from ..manifest import Manifest from ..manifest import Manifest
from ..logger import create_logger from ..logger import create_logger
@ -167,7 +167,7 @@ class DiffMixIn:
"paths", "paths",
metavar="PATH", metavar="PATH",
nargs="*", nargs="*",
type=str, type=PathSpec,
help="paths of items inside the archives to compare; patterns are supported", help="paths of items inside the archives to compare; patterns are supported",
) )
define_exclusion_group(subparser) define_exclusion_group(subparser)

View File

@ -8,7 +8,7 @@ from ._common import with_repository, with_archive
from ._common import build_filter, build_matcher from ._common import build_filter, build_matcher
from ..archive import BackupError, BackupOSError from ..archive import BackupError, BackupOSError
from ..constants import * # NOQA from ..constants import * # NOQA
from ..helpers import archivename_validator from ..helpers import archivename_validator, PathSpec
from ..helpers import remove_surrogates from ..helpers import remove_surrogates
from ..helpers import HardLinkManager from ..helpers import HardLinkManager
from ..helpers import ProgressIndicatorPercent from ..helpers import ProgressIndicatorPercent
@ -177,6 +177,6 @@ class ExtractMixIn:
) )
subparser.add_argument("name", metavar="NAME", type=archivename_validator, help="specify the archive name") subparser.add_argument("name", metavar="NAME", type=archivename_validator, help="specify the archive name")
subparser.add_argument( subparser.add_argument(
"paths", metavar="PATH", nargs="*", type=str, help="paths to extract; patterns are supported" "paths", metavar="PATH", nargs="*", type=PathSpec, help="paths to extract; patterns are supported"
) )
define_exclusion_group(subparser, strip_components=True) define_exclusion_group(subparser, strip_components=True)

View File

@ -6,6 +6,7 @@ from ..constants import * # NOQA
from ..crypto.key import AESOCBRepoKey, CHPORepoKey, Blake2AESOCBRepoKey, Blake2CHPORepoKey from ..crypto.key import AESOCBRepoKey, CHPORepoKey, Blake2AESOCBRepoKey, Blake2CHPORepoKey
from ..crypto.key import AESOCBKeyfileKey, CHPOKeyfileKey, Blake2AESOCBKeyfileKey, Blake2CHPOKeyfileKey from ..crypto.key import AESOCBKeyfileKey, CHPOKeyfileKey, Blake2AESOCBKeyfileKey, Blake2CHPOKeyfileKey
from ..crypto.keymanager import KeyManager from ..crypto.keymanager import KeyManager
from ..helpers import PathSpec
from ..manifest import Manifest from ..manifest import Manifest
from ._common import with_repository from ._common import with_repository
@ -194,7 +195,7 @@ class KeysMixIn:
help="export repository key for backup", help="export repository key for backup",
) )
subparser.set_defaults(func=self.do_key_export) subparser.set_defaults(func=self.do_key_export)
subparser.add_argument("path", metavar="PATH", nargs="?", type=str, help="where to store the backup") subparser.add_argument("path", metavar="PATH", nargs="?", type=PathSpec, help="where to store the backup")
subparser.add_argument( subparser.add_argument(
"--paper", "--paper",
dest="paper", dest="paper",
@ -237,7 +238,7 @@ class KeysMixIn:
) )
subparser.set_defaults(func=self.do_key_import) subparser.set_defaults(func=self.do_key_import)
subparser.add_argument( subparser.add_argument(
"path", metavar="PATH", nargs="?", type=str, help="path to the backup ('-' to read from stdin)" "path", metavar="PATH", nargs="?", type=PathSpec, help="path to the backup ('-' to read from stdin)"
) )
subparser.add_argument( subparser.add_argument(
"--paper", "--paper",

View File

@ -7,7 +7,7 @@ from ._common import with_repository, build_matcher, Highlander
from ..archive import Archive from ..archive import Archive
from ..cache import Cache from ..cache import Cache
from ..constants import * # NOQA from ..constants import * # NOQA
from ..helpers import ItemFormatter, BaseFormatter, archivename_validator from ..helpers import ItemFormatter, BaseFormatter, archivename_validator, PathSpec
from ..manifest import Manifest from ..manifest import Manifest
from ..logger import create_logger from ..logger import create_logger
@ -119,6 +119,6 @@ class ListMixIn:
) )
subparser.add_argument("name", metavar="NAME", type=archivename_validator, help="specify the archive name") subparser.add_argument("name", metavar="NAME", type=archivename_validator, help="specify the archive name")
subparser.add_argument( subparser.add_argument(
"paths", metavar="PATH", nargs="*", type=str, help="paths to list; patterns are supported" "paths", metavar="PATH", nargs="*", type=PathSpec, help="paths to list; patterns are supported"
) )
define_exclusion_group(subparser) define_exclusion_group(subparser)

View File

@ -4,6 +4,7 @@ import os
from ._common import with_repository, Highlander from ._common import with_repository, Highlander
from ..constants import * # NOQA from ..constants import * # NOQA
from ..helpers import EXIT_ERROR from ..helpers import EXIT_ERROR
from ..helpers import PathSpec
from ..helpers import umount from ..helpers import umount
from ..manifest import Manifest from ..manifest import Manifest
from ..remote import cache_if_remote from ..remote import cache_if_remote
@ -180,6 +181,6 @@ class MountMixIn:
) )
define_archive_filters_group(parser) define_archive_filters_group(parser)
parser.add_argument( parser.add_argument(
"paths", metavar="PATH", nargs="*", type=str, help="paths to extract; patterns are supported" "paths", metavar="PATH", nargs="*", type=PathSpec, help="paths to extract; patterns are supported"
) )
define_exclusion_group(parser, strip_components=True) define_exclusion_group(parser, strip_components=True)

View File

@ -5,7 +5,7 @@ from ._common import build_matcher
from ..archive import ArchiveRecreater from ..archive import ArchiveRecreater
from ..constants import * # NOQA from ..constants import * # NOQA
from ..compress import CompressionSpec from ..compress import CompressionSpec
from ..helpers import archivename_validator, comment_validator, ChunkerParams from ..helpers import archivename_validator, comment_validator, PathSpec, ChunkerParams
from ..helpers import timestamp from ..helpers import timestamp
from ..manifest import Manifest from ..manifest import Manifest
@ -205,5 +205,5 @@ class RecreateMixIn:
) )
subparser.add_argument( subparser.add_argument(
"paths", metavar="PATH", nargs="*", type=str, help="paths to recreate; patterns are supported" "paths", metavar="PATH", nargs="*", type=PathSpec, help="paths to recreate; patterns are supported"
) )

View File

@ -15,7 +15,7 @@ from ..helpers import dash_open
from ..helpers import msgpack from ..helpers import msgpack
from ..helpers import create_filter_process from ..helpers import create_filter_process
from ..helpers import ChunkIteratorFileWrapper from ..helpers import ChunkIteratorFileWrapper
from ..helpers import archivename_validator, comment_validator, ChunkerParams from ..helpers import archivename_validator, comment_validator, PathSpec, ChunkerParams
from ..helpers import remove_surrogates from ..helpers import remove_surrogates
from ..helpers import timestamp, archive_ts_now from ..helpers import timestamp, archive_ts_now
from ..helpers import basic_json_data, json_print from ..helpers import basic_json_data, json_print
@ -418,7 +418,7 @@ class TarMixIn:
subparser.add_argument("name", metavar="NAME", type=archivename_validator, help="specify the archive name") subparser.add_argument("name", metavar="NAME", type=archivename_validator, help="specify the archive name")
subparser.add_argument("tarfile", metavar="FILE", help='output tar file. "-" to write to stdout instead.') subparser.add_argument("tarfile", metavar="FILE", help='output tar file. "-" to write to stdout instead.')
subparser.add_argument( subparser.add_argument(
"paths", metavar="PATH", nargs="*", type=str, help="paths to extract; patterns are supported" "paths", metavar="PATH", nargs="*", type=PathSpec, help="paths to extract; patterns are supported"
) )
define_exclusion_group(subparser, strip_components=True) define_exclusion_group(subparser, strip_components=True)

View File

@ -22,7 +22,7 @@ from .misc import ChunkIteratorFileWrapper, open_item, chunkit, iter_separated,
from .parseformat import bin_to_hex, safe_encode, safe_decode from .parseformat import bin_to_hex, safe_encode, safe_decode
from .parseformat import text_to_json, binary_to_json, remove_surrogates, join_cmd from .parseformat import text_to_json, binary_to_json, remove_surrogates, join_cmd
from .parseformat import eval_escapes, decode_dict, positive_int_validator, interval from .parseformat import eval_escapes, decode_dict, positive_int_validator, interval
from .parseformat import SortBySpec, ChunkerParams, FilesCacheMode, partial_format, DatetimeWrapper from .parseformat import PathSpec, SortBySpec, ChunkerParams, FilesCacheMode, partial_format, DatetimeWrapper
from .parseformat import format_file_size, parse_file_size, FileSize, parse_storage_quota from .parseformat import format_file_size, parse_file_size, FileSize, parse_storage_quota
from .parseformat import sizeof_fmt, sizeof_fmt_iec, sizeof_fmt_decimal, Location, text_validator from .parseformat import sizeof_fmt, sizeof_fmt_iec, sizeof_fmt_decimal, Location, text_validator
from .parseformat import format_line, replace_placeholders, PlaceholderError, relative_time_marker_validator from .parseformat import format_line, replace_placeholders, PlaceholderError, relative_time_marker_validator

View File

@ -284,6 +284,12 @@ class PlaceholderReplacer:
replace_placeholders = PlaceholderReplacer() replace_placeholders = PlaceholderReplacer()
def PathSpec(text):
if not text:
raise argparse.ArgumentTypeError("Empty strings are not accepted as paths.")
return text
def SortBySpec(text): def SortBySpec(text):
from ..manifest import AI_HUMAN_SORT_KEYS from ..manifest import AI_HUMAN_SORT_KEYS