Diff
Not logged in

Differences From:

File src/wiki.c part of check-in [6d58613757] - Timeline comments are now rendered as wiki. Wiki changes appear on the timeline. by drh on 2007-10-06 16:37:39. [view]

To:

File src/wiki.c part of check-in [488afb9746] - Enforce well-formedness constraints on wiki pagenames. by drh on 2007-10-06 17:10:47. [view]

@@ -26,8 +26,51 @@
 #include <assert.h>
 #include "config.h"
 #include "wiki.h"
 
+/*
+** Return true if the input string is a well-formed wiki page name.
+**
+** Well-formed wiki page names do not begin or end with whitespace,
+** and do not contain tabs or other control characters and do not
+** contain more than a single space character in a row.  Well-formed
+** names must be between 3 and 100 chracters in length, inclusive.
+*/
+int wiki_name_is_wellformed(const char *z){
+  int i;
+  if( z[0]<=0x20 ){
+    return 0;
+  }
+  for(i=1; z[i]; i++){
+    if( z[i]<0x20 ) return 0;
+    if( z[i]==0x20 && z[i-1]==0x20 ) return 0;
+  }
+  if( z[i-1]==' ' ) return 0;
+  if( i<3 || i>100 ) return 0;
+  return 1;
+}
+
+/*
+** Check a wiki name.  If it is not well-formed, then issue an error
+** and return true.  If it is well-formed, return false.
+*/
+static int check_name(const char *z){
+  if( !wiki_name_is_wellformed(z) ){
+    style_header("Wiki Page Name Error");
+    @ The wiki name "<b>%h(z)</b>" is not well-formed.  Rules for
+    @ wiki page names:
+    @ <ul>
+    @ <li> Must not begin or end with a space.
+    @ <li> Must not contain any control characters, including tab or
+    @      newline.
+    @ <li> Must not have two or more spaces in a row internally.
+    @ <li> Must be between 3 and 100 characters in length.
+    @ </ul>
+    style_footer();
+    return 1;
+  }
+  return 0;
+}
 
 /*
 ** WEBPAGE: wiki
 ** URL: /wiki/PAGENAME
@@ -44,8 +87,9 @@
   login_check_credentials();
   if( !g.okRdWiki ){ login_needed(); return; }
   zPageName = mprintf("%s", g.zExtra);
   dehttpize(zPageName);
+  if( check_name(zPageName) ) return;
   zTag = mprintf("wiki-%s", zPageName);
   rid = db_int(0,
     "SELECT rid FROM tagxref"
     " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
@@ -67,9 +111,9 @@
   blob_init(&wiki, zBody, -1);
   wiki_convert(&wiki, 0);
   blob_reset(&wiki);
   manifest_clear(&m);
-  if( zPageName[0] && ((rid && g.okWrWiki) || (!rid && g.okNewWiki)) ){
+  if( (rid && g.okWrWiki) || (!rid && g.okNewWiki) ){
     @ <hr>
     @ [<a href="%s(g.zBaseURL)/wikiedit/%s(g.zExtra)">Edit</a>]
   }
   style_footer();
@@ -95,8 +139,9 @@
   }
   login_check_credentials();
   zPageName = mprintf("%s", g.zExtra);
   dehttpize(zPageName);
+  if( check_name(zPageName) ) return;
   zTag = mprintf("wiki-%s", zPageName);
   rid = db_int(0,
     "SELECT rid FROM tagxref"
     " WHERE tagid=(SELECT tagid FROM tag WHERE tagname=%Q)"
@@ -147,9 +192,9 @@
     content_deltify(rid, nrid, 0);
     db_end_transaction(0);
     cgi_redirect(mprintf("wiki/%s", g.zExtra));
   }
-  if( P("cancel")!=0 || zPageName[0]==0 ){
+  if( P("cancel")!=0 ){
     cgi_redirect(mprintf("wiki/%s", g.zExtra));
     return;
   }
   if( zBody==0 ){