summaryrefslogtreecommitdiff
path: root/django/core
diff options
context:
space:
mode:
authorHonza Král <honza.kral@gmail.com>2009-10-12 10:16:17 +0000
committerHonza Král <honza.kral@gmail.com>2009-10-12 10:16:17 +0000
commitdfe495fbe8e360ee3b3cd8b29e55ee19d86fc9d2 (patch)
tree16bccad252c6fd2b00e734f275594ae159596e70 /django/core
parent83a3588ff712d5fe44e9692f5cb6a1d020f3ab2f (diff)
[soc2009/model-validation] Merged to trunk at r11603
SECURITY ALERT: Corrected regular expressions for URL and email fields. git-svn-id: http://code.djangoproject.com/svn/django/branches/soc2009/model-validation@11617 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django/core')
-rw-r--r--django/core/handlers/modpython.py4
-rw-r--r--django/core/management/__init__.py77
-rw-r--r--django/core/validators.py4
3 files changed, 81 insertions, 4 deletions
diff --git a/django/core/handlers/modpython.py b/django/core/handlers/modpython.py
index c6dcf23e9a..b1e3e17227 100644
--- a/django/core/handlers/modpython.py
+++ b/django/core/handlers/modpython.py
@@ -134,8 +134,8 @@ class ModPythonRequest(http.HttpRequest):
if not hasattr(self, '_meta'):
self._meta = {
'AUTH_TYPE': self._req.ap_auth_type,
- 'CONTENT_LENGTH': self._req.clength, # This may be wrong
- 'CONTENT_TYPE': self._req.content_type, # This may be wrong
+ 'CONTENT_LENGTH': self._req.headers_in.get('content-length', 0),
+ 'CONTENT_TYPE': self._req.headers_in.get('content-type'),
'GATEWAY_INTERFACE': 'CGI/1.1',
'PATH_INFO': self.path_info,
'PATH_TRANSLATED': None, # Not supported
diff --git a/django/core/management/__init__.py b/django/core/management/__init__.py
index 026e426862..60dcf727e4 100644
--- a/django/core/management/__init__.py
+++ b/django/core/management/__init__.py
@@ -261,6 +261,82 @@ class ManagementUtility(object):
sys.exit(1)
return klass
+ def autocomplete(self):
+ """
+ Output completion suggestions for BASH.
+
+ The output of this function is passed to BASH's `COMREPLY` variable and
+ treated as completion suggestions. `COMREPLY` expects a space
+ separated string as the result.
+
+ The `COMP_WORDS` and `COMP_CWORD` BASH environment variables are used
+ to get information about the cli input. Please refer to the BASH
+ man-page for more information about this variables.
+
+ Subcommand options are saved as pairs. A pair consists of
+ the long option string (e.g. '--exclude') and a boolean
+ value indicating if the option requires arguments. When printing to
+ stdout, a equal sign is appended to options which require arguments.
+
+ Note: If debugging this function, it is recommended to write the debug
+ output in a separate file. Otherwise the debug output will be treated
+ and formatted as potential completion suggestions.
+ """
+ # Don't complete if user hasn't sourced bash_completion file.
+ if not os.environ.has_key('DJANGO_AUTO_COMPLETE'):
+ return
+
+ cwords = os.environ['COMP_WORDS'].split()[1:]
+ cword = int(os.environ['COMP_CWORD'])
+
+ try:
+ curr = cwords[cword-1]
+ except IndexError:
+ curr = ''
+
+ subcommands = get_commands().keys() + ['help']
+ options = [('--help', None)]
+
+ # subcommand
+ if cword == 1:
+ print ' '.join(filter(lambda x: x.startswith(curr), subcommands))
+ # subcommand options
+ # special case: the 'help' subcommand has no options
+ elif cwords[0] in subcommands and cwords[0] != 'help':
+ subcommand_cls = self.fetch_command(cwords[0])
+ # special case: 'runfcgi' stores additional options as
+ # 'key=value' pairs
+ if cwords[0] == 'runfcgi':
+ from django.core.servers.fastcgi import FASTCGI_OPTIONS
+ options += [(k, 1) for k in FASTCGI_OPTIONS]
+ # special case: add the names of installed apps to options
+ elif cwords[0] in ('dumpdata', 'reset', 'sql', 'sqlall',
+ 'sqlclear', 'sqlcustom', 'sqlindexes',
+ 'sqlreset', 'sqlsequencereset', 'test'):
+ try:
+ from django.conf import settings
+ # Get the last part of the dotted path as the app name.
+ options += [(a.split('.')[-1], 0) for a in settings.INSTALLED_APPS]
+ except ImportError:
+ # Fail silently if DJANGO_SETTINGS_MODULE isn't set. The
+ # user will find out once they execute the command.
+ pass
+ options += [(s_opt.get_opt_string(), s_opt.nargs) for s_opt in
+ subcommand_cls.option_list]
+ # filter out previously specified options from available options
+ prev_opts = [x.split('=')[0] for x in cwords[1:cword-1]]
+ options = filter(lambda (x, v): x not in prev_opts, options)
+
+ # filter options by current input
+ options = [(k, v) for k, v in options if k.startswith(curr)]
+ for option in options:
+ opt_label = option[0]
+ # append '=' to options which require args
+ if option[1]:
+ opt_label += '='
+ print opt_label
+ sys.exit(1)
+
def execute(self):
"""
Given the command-line arguments, this figures out which subcommand is
@@ -272,6 +348,7 @@ class ManagementUtility(object):
parser = LaxOptionParser(usage="%prog subcommand [options] [args]",
version=get_version(),
option_list=BaseCommand.option_list)
+ self.autocomplete()
try:
options, args = parser.parse_args(self.argv)
handle_default_options(options)
diff --git a/django/core/validators.py b/django/core/validators.py
index 225dd5cba2..4515ca7a4f 100644
--- a/django/core/validators.py
+++ b/django/core/validators.py
@@ -40,7 +40,7 @@ class RegexValidator(object):
class URLValidator(RegexValidator):
regex = re.compile(
r'^https?://' # http:// or https://
- r'(?:(?:[A-Z0-9]+(?:-*[A-Z0-9]+)*\.)+[A-Z]{2,6}|' #domain...
+ r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?|' #domain...
r'localhost|' #localhost...
r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
r'(?::\d+)?' # optional port
@@ -81,7 +81,7 @@ def validate_integer(value):
email_re = re.compile(
r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*" # dot-atom
r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
- r')@(?:[A-Z0-9]+(?:-*[A-Z0-9]+)*\.)+[A-Z]{2,6}$', re.IGNORECASE) # domain
+ r')@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$', re.IGNORECASE) # domain
validate_email = RegexValidator(email_re, _(u'Enter a valid e-mail address.'), 'invalid')
slug_re = re.compile(r'^[-\w]+$')