mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-03-25 08:55:50 +00:00
Create always safe hrefs
The set of safe characters was inspired by the set of safe characters in URLs. Fixes #229
This commit is contained in:
parent
04b3379172
commit
73e2ccf46a
6 changed files with 16 additions and 16 deletions
|
|
@ -14,7 +14,7 @@ from .. import EVENT_TEMPLATE, TASK_TEMPLATE, VCARD_TEMPLATE, \
|
|||
|
||||
def format_item(item_template, uid=None):
|
||||
# assert that special chars are handled correctly.
|
||||
r = '{}@vdirsyncer'.format(random.random())
|
||||
r = random.random()
|
||||
return Item(item_template.format(r=r, uid=uid or r))
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ class ServerMixin(object):
|
|||
url = url.rstrip('/') + '/' + collection
|
||||
|
||||
rv = {'url': url, 'username': 'bob', 'password': 'bob',
|
||||
'collection': collection, 'unsafe_href_chars': ''}
|
||||
'collection': collection}
|
||||
|
||||
if collection is not None:
|
||||
s = self.storage_class(**rv)
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class TestFilesystemStorage(StorageTests):
|
|||
s = self.storage_class(str(tmpdir), '.txt')
|
||||
s.upload(Item(u'UID:a/b/c'))
|
||||
item_file, = tmpdir.listdir()
|
||||
assert str(item_file).endswith('a_b_c.txt')
|
||||
assert '/' not in item_file.basename and item_file.isfile()
|
||||
|
||||
def test_too_long_uid(self, tmpdir):
|
||||
s = self.storage_class(str(tmpdir), '.txt')
|
||||
|
|
|
|||
|
|
@ -341,15 +341,14 @@ class DavStorage(Storage):
|
|||
}
|
||||
|
||||
def __init__(self, url, username='', password='', verify=True, auth=None,
|
||||
useragent=USERAGENT, unsafe_href_chars='@',
|
||||
verify_fingerprint=None, auth_cert=None, **kwargs):
|
||||
useragent=USERAGENT, verify_fingerprint=None, auth_cert=None,
|
||||
**kwargs):
|
||||
super(DavStorage, self).__init__(**kwargs)
|
||||
|
||||
url = url.rstrip('/') + '/'
|
||||
self.session = DavSession(url, username, password, verify, auth,
|
||||
useragent, verify_fingerprint,
|
||||
auth_cert)
|
||||
self.unsafe_href_chars = unsafe_href_chars
|
||||
|
||||
# defined for _repr_attributes
|
||||
self.username = username
|
||||
|
|
@ -369,7 +368,7 @@ class DavStorage(Storage):
|
|||
return _normalize_href(self.session.url, *args, **kwargs)
|
||||
|
||||
def _get_href(self, item):
|
||||
href = utils.generate_href(item.ident, unsafe=self.unsafe_href_chars)
|
||||
href = utils.generate_href(item.ident)
|
||||
return self._normalize_href(href + self.fileext)
|
||||
|
||||
def _is_item_mimetype(self, mimetype):
|
||||
|
|
|
|||
|
|
@ -87,9 +87,7 @@ class FilesystemStorage(Storage):
|
|||
return os.path.join(self.path, to_native(href, self.encoding))
|
||||
|
||||
def _get_href(self, ident):
|
||||
# XXX: POSIX only defines / and \0 as invalid chars, but we should make
|
||||
# this work crossplatform.
|
||||
return generate_href(ident, '/') + self.fileext
|
||||
return generate_href(ident) + self.fileext
|
||||
|
||||
def list(self):
|
||||
for fname in os.listdir(self.path):
|
||||
|
|
|
|||
|
|
@ -8,6 +8,11 @@ from .compat import iteritems, to_unicode
|
|||
from .. import exceptions
|
||||
|
||||
|
||||
SAFE_UID_CHARS = ('abcdefghijklmnopqrstuvwxyz'
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
'0123456789_.-+')
|
||||
|
||||
|
||||
_missing = object()
|
||||
|
||||
|
||||
|
|
@ -159,10 +164,8 @@ class cached_property(object):
|
|||
return result
|
||||
|
||||
|
||||
def generate_href(ident=None, unsafe=''):
|
||||
if ident and \
|
||||
ident.encode('ascii', 'ignore').decode('ascii') == ident:
|
||||
for char in unsafe:
|
||||
ident = ident.replace(char, '_')
|
||||
def generate_href(ident=None, safe=SAFE_UID_CHARS):
|
||||
if not ident or set(ident) - set(safe):
|
||||
return to_unicode(uuid.uuid4().hex)
|
||||
else:
|
||||
return ident
|
||||
return to_unicode(uuid.uuid4().hex)
|
||||
|
|
|
|||
Loading…
Reference in a new issue