# HG changeset patch # User Dan # Date 1203369262 18000 # Node ID e7ad98914d065c2cd6858c7a8329d2bc7b4c0517 # Parent fa51b1b5eae6d820ca62450e8549bab08f690daf# Parent f5718d7c2a6aa79a505268ff40cb42706c588ee3 Merging Nighthawk and Scribus branches diff -r fa51b1b5eae6 -r e7ad98914d06 includes/clientside/static/misc.js --- a/includes/clientside/static/misc.js Mon Feb 18 16:13:56 2008 -0500 +++ b/includes/clientside/static/misc.js Mon Feb 18 16:14:22 2008 -0500 @@ -872,3 +872,80 @@ } return myWidth; } + +/** + * Sanitizes a page URL string so that it can safely be stored in the database. + * @param string Page ID to sanitize + * @return string Cleaned text + */ + +function sanitize_page_id(page_id) +{ + // Remove character escapes + page_id = dirtify_page_id(page_id); + + var regex = new RegExp('[A-Za-z0-9\\[\\]\./:;\(\)@_-]', 'g'); + pid_clean = page_id.replace(regex, 'X'); + var pid_dirty = []; + for ( var i = 0; i < pid_clean.length; i++ ) + pid_dirty[i] = pid_clean.substr(i, 1); + + for ( var i = 0; i < pid_dirty.length; i++ ) + { + var char = pid_dirty[i]; + if ( char == 'X' ) + continue; + var cid = char.charCodeAt(0); + cid = cid.toString(16).toUpperCase(); + if ( cid.length < 2 ) + { + cid = '0' + cid; + } + pid_dirty[i] = "." + cid; + } + + var pid_chars = []; + for ( var i = 0; i < page_id.length; i++ ) + pid_chars[i] = page_id.substr(i, 1); + + var page_id_cleaned = ''; + + for ( var id in pid_chars ) + { + var char = pid_chars[id]; + if ( pid_dirty[id] == 'X' ) + page_id_cleaned += char; + else + page_id_cleaned += pid_dirty[id]; + } + + return page_id_cleaned; +} + +/** + * Removes character escapes in a page ID string + * @param string Page ID string to dirty up + * @return string + */ + +function dirtify_page_id(page_id) +{ + // First, replace spaces with underscores + page_id = page_id.replace(/ /g, '_'); + + var matches = page_id.match(/\.[A-Fa-f0-9][A-Fa-f0-9]/g); + + if ( matches != null ) + { + for ( var i = 0; i < matches.length; i++ ) + { + var match = matches[i]; + var byt = (match.substr(1)).toUpperCase(); + var code = eval("0x" + byt); + var regex = new RegExp('\\.' + byt, 'g'); + page_id = page_id.replace(regex, String.fromCharCode(code)); + } + } + + return page_id; +} diff -r fa51b1b5eae6 -r e7ad98914d06 includes/pageprocess.php --- a/includes/pageprocess.php Mon Feb 18 16:13:56 2008 -0500 +++ b/includes/pageprocess.php Mon Feb 18 16:14:22 2008 -0500 @@ -471,24 +471,26 @@ /** * Creates the page if it doesn't already exist. + * @param string Optional page title. * @return bool True on success, false on failure. */ - function create_page() + function create_page($title = false) { global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; // Do we have permission to create the page? if ( !$this->perms->get_permissions('create_page') ) { - $this->raise_error('You do not have permission to create this page.'); + $this->raise_error($lang->get('pagetools_create_err_no_permission')); return false; } // Does it already exist? if ( $this->page_exists ) { - $this->raise_error('The page already exists.'); + $this->raise_error($lang->get('pagetools_create_err_already_exists')); return false; } @@ -497,17 +499,17 @@ // We can't create special, admin, or external pages. if ( $this->namespace == 'Special' || $this->namespace == 'Admin' || $this->namespace == 'Anonymous' ) { - $this->raise_error('You cannot create Special or Admin pages - they can\'t be stored in the database.'); + $this->raise_error($lang->get('pagetools_create_err_nodb_namespace')); return false; } // Guess the proper title - $name = dirtify_page_id($this->page_id); + $name = ( !empty($title) ) ? $title : dirtify_page_id($this->page_id); // Check for the restricted Project: prefix if ( substr($this->page_id, 0, 8) == 'Project:' ) { - $this->raise_error('The prefix "Project:" is reserved for internal links and can\'t be used on a page name.'); + $this->raise_error($lang->get('pagetools_create_err_reserved_prefix')); return false; } @@ -546,6 +548,13 @@ if ( !$q ) $db->_die('PageProcessor page creation - text stage'); + // Query 3: Log entry + $db->sql_query('INSERT INTO ' . table_prefix."logs(time_id, date_string, log_type, action, author, page_id, namespace)\n" + . " VALUES ( " . time() . ", '" . enano_date('d M Y h:i a') . "', 'page', 'create', \n" + . " '" . $db->escape($session->username) . "', '" . $db->escape($this->page_id) . "', '" . $this->namespace . "');"); + if ( !$q ) + $db->_die('PageProcessor page creation - logging stage'); + // Page created. We're good! return true; } @@ -575,11 +584,13 @@ } // Does the page "exist"? + $pathskey = $paths->nslist[$namespace] . $page_id_cleaned; + if ( $paths->page_id == $page_id && $paths->namespace == $namespace && !$paths->page_exists && ( $this->namespace != 'Admin' || ($this->namespace == 'Admin' && !function_exists($fname) ) ) ) { $this->page_exists = false; } - else if ( !isset( $paths->pages[ $paths->nslist[$namespace] . $page_id ] ) && ( $this->namespace == 'Admin' && !function_exists($fname) ) ) + else if ( !isset( $paths->pages[ $pathskey ] ) && ( ( $this->namespace == 'Admin' && !function_exists($fname) ) || ( $this->namespace != 'Admin' ) ) ) { $this->page_exists = false; } diff -r fa51b1b5eae6 -r e7ad98914d06 language/english/tools.json --- a/language/english/tools.json Mon Feb 18 16:13:56 2008 -0500 +++ b/language/english/tools.json Mon Feb 18 16:14:22 2008 -0500 @@ -88,14 +88,23 @@ pagetools: { // Create a page - create_err_title: 'The page could not be created.', - create_err_name_invalid: 'The name "%page_name%" is invalid.', - create_err_project_shortcut: 'The page title can\'t start with "Project:" because this prefix is reserved for a parser shortcut.', - create_err_already_exist: 'The page already exists.', + create_err_invalid_namespace: 'You have selected an invalid page type.', + create_err_invalid_urlname: 'Please enter a title for your page and a custom URL if desired.', + create_err_already_exists: 'A page with that URL already exists. Please enter another title or enter a custom URL. (You can have two pages with the same name, but not two pages with the same URL.)', + create_err_no_permission: 'You don\'t have permission to create this page. Try another URL or title; if that does not work, please contact the site administration for permission to create pages.', + create_err_nodb_namespace: 'You cannot create Special or Admin pages - they can\'t be stored in the database.', + create_err_reserved_prefix: 'The prefix "Project:" is reserved for internal links and can\'t be used on a page name.', - create_blurb: 'Using the form below you can create a page.', - create_namespace_none: '[No prefix]', - create_btn_create: 'Create Page', + create_blurb: 'Add a new page to the site.', + create_field_title: 'Page title:', + create_field_namespace: 'Page type:', + create_group_advanced: 'Advanced options', + create_field_url_auto: 'Generate a URL based on the title', + create_field_url_manual: 'Enter a custom page URL', + create_field_url: 'Page ID:', + create_field_preview: 'Preview of URL:', + create_field_preview_hint: '(Requires Javascript support)', + create_btn_create: 'Create page', // All pages allpages_blurb: 'Below is a list of all of the pages on this website.', diff -r fa51b1b5eae6 -r e7ad98914d06 plugins/SpecialPageFuncs.php --- a/plugins/SpecialPageFuncs.php Mon Feb 18 16:13:56 2008 -0500 +++ b/plugins/SpecialPageFuncs.php Mon Feb 18 16:14:22 2008 -0500 @@ -10,7 +10,7 @@ /* * Enano - an open-source CMS capable of wiki functions, Drupal-like sidebar blocks, and everything in between - * Version 1.1.1 + * Version 1.1.2 (Caoineag alpha 2) * Copyright (C) 2006-2007 Dan Fuhry * * This program is Free Software; you can redistribute and/or modify it under the terms of the GNU General Public License @@ -74,6 +74,183 @@ global $db, $session, $paths, $template, $plugins; // Common objects global $lang; + $whitelist_ns = array('Article', 'User', 'Help', 'Template', 'Category', 'Project'); + $code = $plugins->setHook('page_create_ns_whitelist'); + foreach ( $code as $cmd ) + { + eval($cmd); + } + + $errors = array(); + + switch ( isset($_POST['page_title']) ) + { + case true: + // "Create page" was clicked + + // + // VALIDATION CODE + // + + // Check namespace + $namespace = ( isset($_POST['namespace']) ) ? $_POST['namespace'] : 'Article'; + if ( !in_array($namespace, $whitelist_ns) ) + { + $errors[] = $lang->get('pagetools_create_err_invalid_namespace'); + } + + // Check title and figure out urlname + $title = $_POST['page_title']; + $urlname = $_POST['page_title']; + if ( @$_POST['custom_url'] === 'yes' && isset($_POST['urlname']) ) + { + $urlname = $_POST['urlname']; + } + $urlname = sanitize_page_id($urlname); + if ( $urlname == '.00' || empty($urlname) ) + { + $errors[] = $lang->get('pagetools_create_err_invalid_urlname'); + } + + // Validate page existence + $pathskey = $paths->nslist[$namespace] . $urlname; + if ( isPage($pathskey) ) + { + $errors[] = $lang->get('pagetools_create_err_already_exists'); + } + + // Validate permissions + $perms = $session->fetch_page_acl($urlname, $namespace); + if ( !$perms->get_permissions('create_page') ) + { + $errors[] = $lang->get('pagetools_create_err_no_permission'); + } + + // Run hooks + $code = $plugins->setHook('page_create_request'); + foreach ( $code as $cmd ) + { + eval($cmd); + } + + // Create the page + if ( count($errors) < 1 ) + { + $page = new PageProcessor($urlname, $namespace); + $page->create_page($title); + if ( $error = $page->pop_error() ) + { + do + { + $errors[] = $error; + } + while ( $error = $page->pop_error() ); + } + else + { + redirect(makeUrlNS($namespace, $urlname) . '#do:edit', '', '', 0); + return true; + } + } + + break; + } + + $template->header(); + + echo $lang->get('pagetools_create_blurb'); + + if ( count($errors) > 0 ) + { + echo '
'; + echo $lang->get('pagetools_create_field_title'); + echo ' '; + echo '
'; + + echo ''; + echo $lang->get('pagetools_create_field_namespace'); + echo ' '; + echo '
'; + + echo ''; + + echo ''; + echo ''; + echo '
'; + + echo ''; + + echo ''; + + $template->footer(); +} + +function page_Special_CreatePage_Old() +{ + global $db, $session, $paths, $template, $plugins; // Common objects + global $lang; + if ( isset($_POST['do']) ) { $p = $_POST['pagename'];