=== added file 'django/template/loaders/util.py'
--- django/template/loaders/util.py	1970-01-01 00:00:00 +0000
+++ django/template/loaders/util.py	2007-07-22 16:46:18 +0000
@@ -0,0 +1,19 @@
+"""
+Utility functions for template loaders.
+"""
+
+from os.path import abspath, join
+
+def get_template_sources(template_name, template_dirs=None):
+    """
+    Return a generater that will return the full paths of possible template
+    locations given the template_name and a list of template_dirs.
+    """
+    if not template_dirs:
+        raise StopIteration
+    for template_dir in template_dirs:
+        full_template_dir = abspath(join(template_dir, template_name))
+        # Security check to ensure that we are still in the template directory
+        # after the os.path.join (see ticket #4952).
+        if full_template_dir.startswith(template_dir):
+            yield full_template_dir

=== added directory 'tests/regressiontests/template_loaders'
=== added file 'tests/regressiontests/template_loaders/__init__.py'
=== added file 'tests/regressiontests/template_loaders/models.py'
=== added file 'tests/regressiontests/template_loaders/tests.py'
--- tests/regressiontests/template_loaders/tests.py	1970-01-01 00:00:00 +0000
+++ tests/regressiontests/template_loaders/tests.py	2007-07-22 16:48:14 +0000
@@ -0,0 +1,24 @@
+"""
+>>> template_dirs = ['/dir1', '/dir2']
+
+>>> list(get_template_sources('index.html', template_dirs))
+['/dir1/index.html', '/dir2/index.html']
+
+>>> list(get_template_sources('/etc/passwd', template_dirs))
+[]
+
+>>> list(get_template_sources('etc/passwd', template_dirs))
+['/dir1/etc/passwd', '/dir2/etc/passwd']
+
+>>> list(get_template_sources('../etc/passwd', template_dirs))
+[]
+
+>>> list(get_template_sources('../../../etc/passwd', template_dirs))
+[]
+"""
+
+from django.template.loaders.util import get_template_sources
+
+if __name__ == "__main__":
+    import doctest
+    doctest.testmod()

=== modified file 'django/template/loaders/app_directories.py'
--- django/template/loaders/app_directories.py	2007-07-06 03:07:02 +0000
+++ django/template/loaders/app_directories.py	2007-07-22 15:50:40 +0000
@@ -1,9 +1,14 @@
-# Wrapper for loading templates from "template" directories in installed app packages.
+"""
+Wrapper for loading templates from "template" directories in INSTALLED_APPS
+packages.
+"""
+
+import os
 
 from django.conf import settings
 from django.core.exceptions import ImproperlyConfigured
 from django.template import TemplateDoesNotExist
-import os
+from django.template.loaders.util import get_template_sources
 
 # At compile time, cache the directories to search.
 app_template_dirs = []
@@ -27,11 +32,9 @@
 # It won't change, so convert it to a tuple to save memory.
 app_template_dirs = tuple(app_template_dirs)
 
-def get_template_sources(template_name, template_dirs=None):
-    for template_dir in app_template_dirs:
-        yield os.path.join(template_dir, template_name)
-
 def load_template_source(template_name, template_dirs=None):
+    if not template_dirs:
+        template_dirs = app_template_dirs
     for filepath in get_template_sources(template_name, template_dirs):
         try:
             return (open(filepath).read().decode(settings.FILE_CHARSET), filepath)

=== modified file 'django/template/loaders/filesystem.py'
--- django/template/loaders/filesystem.py	2007-07-06 03:07:02 +0000
+++ django/template/loaders/filesystem.py	2007-07-22 15:47:26 +0000
@@ -1,16 +1,14 @@
-# Wrapper for loading templates from the filesystem.
+"""
+Wrapper for loading templates from the filesystem.
+"""
 
 from django.conf import settings
 from django.template import TemplateDoesNotExist
-import os
+from django.template.loaders.util import get_template_sources
 
-def get_template_sources(template_name, template_dirs=None):
+def load_template_source(template_name, template_dirs=None):
     if not template_dirs:
         template_dirs = settings.TEMPLATE_DIRS
-    for template_dir in template_dirs:
-        yield os.path.join(template_dir, template_name)
-
-def load_template_source(template_name, template_dirs=None):
     tried = []
     for filepath in get_template_sources(template_name, template_dirs):
         try:

