Fixed #24978 -- Escaped special characters in loaddata fixture paths

This commit is contained in:
Moritz Sichert 2015-06-13 12:20:05 +02:00 committed by Tim Graham
parent d58573e60d
commit 98df288dda
5 changed files with 68 additions and 1 deletions

View File

@ -21,6 +21,7 @@ from django.utils import lru_cache
from django.utils._os import upath from django.utils._os import upath
from django.utils.encoding import force_text from django.utils.encoding import force_text
from django.utils.functional import cached_property from django.utils.functional import cached_property
from django.utils.glob import glob_escape
try: try:
import bz2 import bz2
@ -209,7 +210,8 @@ class Command(BaseCommand):
if self.verbosity >= 2: if self.verbosity >= 2:
self.stdout.write("Checking %s for fixtures..." % humanize(fixture_dir)) self.stdout.write("Checking %s for fixtures..." % humanize(fixture_dir))
fixture_files_in_dir = [] fixture_files_in_dir = []
for candidate in glob.iglob(os.path.join(fixture_dir, fixture_name + '*')): path = os.path.join(fixture_dir, fixture_name)
for candidate in glob.iglob(glob_escape(path) + '*'):
if os.path.basename(candidate) in targets: if os.path.basename(candidate) in targets:
# Save the fixture_dir and fixture_name for future error messages. # Save the fixture_dir and fixture_name for future error messages.
fixture_files_in_dir.append((candidate, fixture_dir, fixture_name)) fixture_files_in_dir.append((candidate, fixture_dir, fixture_name))

36
django/utils/glob.py Normal file
View File

@ -0,0 +1,36 @@
from __future__ import unicode_literals
import os.path
import re
from django.utils import six
# backport of Python 3.4's glob.escape
try:
from glob import escape as glob_escape
except ImportError:
_magic_check = re.compile('([*?[])')
if six.PY3:
_magic_check_bytes = re.compile(b'([*?[])')
def glob_escape(pathname):
"""
Escape all special characters.
"""
drive, pathname = os.path.splitdrive(pathname)
if isinstance(pathname, bytes):
pathname = _magic_check_bytes.sub(br'[\1]', pathname)
else:
pathname = _magic_check.sub(r'[\1]', pathname)
return drive + pathname
else:
def glob_escape(pathname):
"""
Escape all special characters.
"""
drive, pathname = os.path.splitdrive(pathname)
pathname = _magic_check.sub(r'[\1]', pathname)
return drive + pathname

View File

@ -0,0 +1,10 @@
[
{
"pk": "1",
"model": "fixtures.article",
"fields": {
"headline": "How To Deal With Special Characters",
"pub_date": "2006-06-16 12:00:00"
}
}
]

View File

@ -224,6 +224,10 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
"Unknown model in excludes: fixtures.FooModel"): "Unknown model in excludes: fixtures.FooModel"):
self._dumpdata_assert(['fixtures', 'sites'], '', exclude_list=['fixtures.FooModel']) self._dumpdata_assert(['fixtures', 'sites'], '', exclude_list=['fixtures.FooModel'])
def test_load_fixture_with_special_characters(self):
management.call_command('loaddata', 'fixture?with[special]chars*', verbosity=0)
self.assertQuerysetEqual(Article.objects.all(), ['<Article: How To Deal With Special Characters>'])
def test_dumpdata_with_filtering_manager(self): def test_dumpdata_with_filtering_manager(self):
spy1 = Spy.objects.create(name='Paul') spy1 = Spy.objects.create(name='Paul')
spy2 = Spy.objects.create(name='Alex', cover_blown=True) spy2 = Spy.objects.create(name='Alex', cover_blown=True)

View File

@ -0,0 +1,15 @@
from __future__ import unicode_literals
from django.test import SimpleTestCase
from django.utils.glob import glob_escape
class TestUtilsGlob(SimpleTestCase):
def test_glob_escape(self):
filename = '/my/file?/name[with special chars*'
expected = '/my/file[?]/name[[]with special chars[*]'
filename_b = b'/my/file?/name[with special chars*'
expected_b = b'/my/file[?]/name[[]with special chars[*]'
self.assertEqual(glob_escape(filename), expected)
self.assertEqual(glob_escape(filename_b), expected_b)