hostname, istty2, log, parse_date_or_fatal, parse_num,
path_components, progress, qprogress, resolve_parent,
saved_errors, stripped_path_components,
- userfullname, username)
+ userfullname, username, valid_save_name)
optspec = """
if is_reverse and opt.remote:
o.fatal("don't use -r in reverse mode; it's automatic")
-if opt.name and opt.name.startswith('.'):
+if opt.name and not valid_save_name(opt.name):
o.fatal("'%s' is not a valid branch name" % opt.name)
refname = opt.name and 'refs/heads/%s' % opt.name or None
if opt.remote or is_reverse:
from bup import hashsplit, git, options, client
from bup.helpers import (add_error, handle_ctrl_c, hostname, log, parse_num,
qprogress, reprogress, saved_errors,
- userfullname, username)
+ userfullname, username, valid_save_name)
optspec = """
o.fatal("don't use -r in reverse mode; it's automatic")
start_time = time.time()
-if opt.name and opt.name.startswith('.'):
+if opt.name and not valid_save_name(opt.name):
o.fatal("'%s' is not a valid branch name." % opt.name)
refname = opt.name and 'refs/heads/%s' % opt.name or None
if opt.noop or opt.copy:
return time.strftime('%z', localtime(t))
def to_py_time(x):
return x
+
+
+_some_invalid_save_parts_rx = re.compile(r'[[ ~^:?*\\]|\.\.|//|@{')
+
+def valid_save_name(name):
+ # Enforce a superset of the restrictions in git-check-ref-format(1)
+ if name == '@' \
+ or name.startswith('/') or name.endswith('/') \
+ or name.endswith('.'):
+ return False
+ if _some_invalid_save_parts_rx.search(name):
+ return False
+ for c in name:
+ if ord(c) < 0x20 or ord(c) == 0x7f:
+ return False
+ for part in name.split('/'):
+ if part.startswith('.') or part.endswith('.lock'):
+ return False
+ return True
del os.environ['TZ']
except KeyError:
pass
+
+@wvtest
+def test_valid_save_name():
+ with no_lingering_errors():
+ valid = helpers.valid_save_name
+ WVPASS(valid('x'))
+ WVPASS(valid('x@'))
+ WVFAIL(valid('@'))
+ WVFAIL(valid('/'))
+ WVFAIL(valid('/foo'))
+ WVFAIL(valid('foo/'))
+ WVFAIL(valid('/foo/'))
+ WVFAIL(valid('foo//bar'))
+ WVFAIL(valid('.'))
+ WVFAIL(valid('bar.'))
+ WVFAIL(valid('foo@{'))
+ for x in ' ~^:?*[\\':
+ WVFAIL(valid('foo' + x))
+ for i in range(20):
+ WVFAIL(valid('foo' + chr(i)))
+ WVFAIL(valid('foo' + chr(0x7f)))
+ WVFAIL(valid('foo..bar'))
+ WVFAIL(valid('bar.lock/baz'))
+ WVFAIL(valid('foo/bar.lock/baz'))
+ WVFAIL(valid('.bar/baz'))
+ WVFAIL(valid('foo/.bar/baz'))