Commit 98df288d authored by Moritz Sichert's avatar Moritz Sichert Committed by Tim Graham
Browse files

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

parent d58573e6
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ from django.utils import lru_cache
from django.utils._os import upath
from django.utils.encoding import force_text
from django.utils.functional import cached_property
from django.utils.glob import glob_escape

try:
    import bz2
@@ -209,7 +210,8 @@ class Command(BaseCommand):
            if self.verbosity >= 2:
                self.stdout.write("Checking %s for fixtures..." % humanize(fixture_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:
                    # Save the fixture_dir and fixture_name for future error messages.
                    fixture_files_in_dir.append((candidate, fixture_dir, fixture_name))

django/utils/glob.py

0 → 100644
+36 −0
Original line number Diff line number Diff line
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
+10 −0
Original line number Diff line number Diff line
[
    {
        "pk": "1",
        "model": "fixtures.article",
        "fields": {
            "headline": "How To Deal With Special Characters",
            "pub_date": "2006-06-16 12:00:00"
        }
    }
]
+4 −0
Original line number Diff line number Diff line
@@ -224,6 +224,10 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
                "Unknown model in excludes: 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):
        spy1 = Spy.objects.create(name='Paul')
        spy2 = Spy.objects.create(name='Alex', cover_blown=True)
+15 −0
Original line number Diff line number Diff line
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)