changeset 188:bfe3979bf323

More validation for the new page form.
author Ludovic Chabant <ludovic@chabant.com>
date Tue, 04 Feb 2014 23:55:29 -0800
parents 5ac0b5fe4cee
children b69e957fd89a
files wikked/fs.py wikked/views/edit.py
diffstat 2 files changed, 21 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/wikked/fs.py	Tue Feb 04 23:07:14 2014 -0800
+++ b/wikked/fs.py	Tue Feb 04 23:55:29 2014 -0800
@@ -6,7 +6,8 @@
 import fnmatch
 import logging
 import itertools
-from utils import PageNotFoundError, NamespaceNotFoundError
+from utils import (PageNotFoundError, NamespaceNotFoundError,
+        split_page_url)
 
 
 META_ENDPOINT = '_meta'
@@ -15,6 +16,9 @@
 logger = logging.getLogger(__name__)
 
 
+valid_filename_pattern = re.compile('^[\w\.\-\(\)\[\]\\/]+$', re.UNICODE)
+
+
 class PageInfo(object):
     def __init__(self, url, path):
         self.url = url
@@ -127,12 +131,7 @@
         return PageInfo(url, path)
 
     def _getPhysicalPath(self, url, is_file=True, make_new=False):
-        endpoint = None
-        m = re.match(r'(\w[\w\d]+)\:(.*)', url)
-        if m:
-            endpoint = str(m.group(1))
-            url = str(m.group(2)).strip()
-
+        endpoint, url = split_page_url(url)
         if url[0] != '/':
             raise ValueError("Page URLs need to be absolute: " + url)
         if string.find(url, '..') >= 0:
@@ -146,15 +145,23 @@
 
         # Make the URL into a relative file-system path.
         url_path = url[1:].replace('/', os.sep)
+        if url_path[0] == os.sep:
+            raise ValueError("Page URLs can only have one slash at the "
+                    "beginning. Got: %s" % url)
 
         # If we want a non-existing file's path, just build that.
         if make_new:
+            if (url_path[-1] == os.sep or
+                    not valid_filename_pattern.match(url_path)):
+                raise ValueError("Invalid URL: %s" % url_path)
             return os.path.join(root, url_path + '.' + self.default_extension)
 
         # Find the right file-system entry for this URL.
         url_path = os.path.join(root, url_path)
         if is_file:
             dirname, basename = os.path.split(url_path)
+            if basename == '':
+                raise ValueError("Invalid URL: %s" % url_path)
             if not os.path.isdir(dirname):
                 self._throwNotFoundError(url, root, is_file)
 
--- a/wikked/views/edit.py	Tue Feb 04 23:07:14 2014 -0800
+++ b/wikked/views/edit.py	Tue Feb 04 23:55:29 2014 -0800
@@ -150,7 +150,13 @@
     if path is None:
         abort(400)
     path = url_from_viewarg(path)
-    if g.wiki.pageExists(path):
+    try:
+        # Check that there's no page with that name already, and that
+        # the name can be correctly mapped to a filename.
+        if g.wiki.pageExists(path):
+            raise Exception("Page '%s' already exists" % path)
+        g.wiki.fs.getPhysicalPagePath(path, make_new=True)
+    except Exception:
         return '"This page name is invalid or unavailable"'
     return '"true"'