From 9fb268e7e4750c2925327a9c026d2f2fac9cf5d4 Mon Sep 17 00:00:00 2001 From: Cameron <e107inc@gmail.com> Date: Wed, 29 Apr 2015 10:22:46 -0700 Subject: [PATCH] Fixes #559 - installer issue when no database found or created. --- e107_handlers/e_parse_class.php | 165 ++++++++++++++++++++--- e107_handlers/theme_handler.php | 2 +- e107_languages/English/lan_installer.php | 5 +- install.php | 68 ++++++---- 4 files changed, 193 insertions(+), 47 deletions(-) diff --git a/e107_handlers/e_parse_class.php b/e107_handlers/e_parse_class.php index 1297a0802..60892dc9d 100644 --- a/e107_handlers/e_parse_class.php +++ b/e107_handlers/e_parse_class.php @@ -250,6 +250,7 @@ class e_parse extends e_parser public function __construct() { // initialise the type of UTF-8 processing methods depending on PHP version and mb string extension + $this->init(); $this->initCharset(); @@ -496,6 +497,7 @@ class e_parse extends e_parser $core_pref = e107::getConfig(); if (is_array($data)) { + $ret = array(); foreach ($data as $key => $var) { //Fix - sanitize keys as well @@ -514,14 +516,15 @@ class e_parse extends e_parser if ($mod != 'pReFs') //XXX We're not saving prefs. { - $data = $this->preFilter($data); // used by bb_xxx.php toDB() functions. bb_code.php toDB() allows us to properly bypass HTML cleaning below. + $data = $this->preFilter($data); // used by bb_xxx.php toDB() functions. bb_code.php toDB() allows us to properly bypass HTML cleaning below. // if(strlen($data) != strlen(strip_tags($data))) // html tags present. // strip_tags() doesn't function doesnt look for unclosed '>'. - if((strpos($data,'[html]') !== false || preg_match('#(?<=<)\w+(?=[^<]*?>)#', $data)) && strpos($mod, 'no_html') === false) + if((strpos($data,'[html]') !== false || htmlentities($data, ENT_NOQUOTES,'UTF-8') != $data || preg_match('#(?<=<)\w+(?=[^<]*?>)#', $data)) && strpos($mod, 'no_html') === false) { $this->isHtml = true; $data = $this->cleanHtml($data); // sanitize all html. - $data = urldecode($data); // symptom of cleaning the HTML - urlencodes src attributes containing { and } .eg. {e_BASE} + + // $data = urldecode($data); //XXX Commented out : NO LONGER REQUIRED. symptom of cleaning the HTML - urlencodes src attributes containing { and } .eg. {e_BASE} } else // caused double-encoding of '&' @@ -1893,6 +1896,11 @@ class e_parse extends e_parser return trim($ret_parser); } + + + + + /** * Use it on html attributes to avoid breaking markup . * @example echo "<a href='#' title='".$tp->toAttribute($text)."'>Hello</a>"; @@ -1900,9 +1908,11 @@ class e_parse extends e_parser function toAttribute($text) { // URLs posted without HTML access may have an & in them. - $text = str_replace('&', '&', $text); + // Xhtml compliance. $text = htmlspecialchars($text, ENT_QUOTES, 'UTF-8'); + + if(!preg_match('/&#|\'|"|<|>/s', $text)) { $text = $this->replaceConstants($text); @@ -2657,9 +2667,13 @@ class e_parser protected $scriptTags = array('script','applet','iframe','form','input','button'); //allowed when $pref['post_script'] is enabled. protected $blockTags = array('pre','div','h1','h2','h3','h4','h5','h6','blockquote'); // element includes its own line-break. - + + + private $scriptAccess = false; // nobody. + public function __construct() { + $this->init(); /* $meths = get_class_methods('DomDocument'); @@ -2673,7 +2687,9 @@ class e_parser */ function init() { - $this->domObj = new DOMDocument(); + $this->domObj = new DOMDocument(); + + } /** @@ -2703,9 +2719,30 @@ class e_parser public function setAllowedTags($array=array()) { $this->allowedTags = $array; - } + } - /** + /** + * Set Script Access + * @param $val int e_UC_MEMBER, e_UC_NOBODY, e_UC_MAINADMIN or userclass number. + */ + public function setScriptAccess($val) + { + $this->scriptAccess = $val; + } + + public function getAllowedTags() + { + return $this->allowedTags; + + } + + + public function getScriptAccess() + { + return $this->scriptAccess; + } + + /** * Set Allowed Attributes. * @param $array */ @@ -3308,7 +3345,10 @@ TMPL; // -------------------- Encoding ---------------- - echo "<h2>e107 Parser Test</h2>"; + $acc = $this->getScriptAccess(); + $accName = e107::getUserclass()->uc_get_classname($acc); + + echo "<h2>e107 Parser Test <small>with script access by <span class='label label-warning'>".$accName."</span></small></h2>"; echo"<h3>User-input <small>(eg. from \$_POST)</small></h3>"; print_a($text); @@ -3338,6 +3378,32 @@ TMPL; echo "<h3>User-input ≫ toDb(\$text, true, false, 'no_html')</h3>"; print_a($dbText2); + // toClean + $filter3 = $tp->filter($text, 'wds'); + echo "<h3>User-input ≫ filter(\$text, 'wds')</h3>"; + print_a( $filter3); + + // Filter by String. + $filter1 = $tp->filter($text,'str'); + echo "<h3>User-input ≫ filter(\$text, 'str')</h3>"; + print_a($filter1); + + // Filter by Encoded. + $filter2 = $tp->filter($text,'enc'); + echo "<h3>User-input ≫ filter(\$text, 'enc')</h3>"; + print_a($filter2); + + + // toAttribute + $toAtt = $tp->toAttribute($text); + echo "<h3>User-input ≫ toAttribute(\$text)</h3>"; + print_a($toAtt); + + // toEmail + $toEmail = $tp->toEmail($text); + echo "<h3>User-input ≫ toEmail(\$text)</h3>"; + print_a($toEmail); + echo "</div>"; @@ -3360,6 +3426,11 @@ TMPL; if(!empty($advanced)) { + + echo "<h3>Allowed Tags</h3>"; + print_a($this->allowedTags); + + echo "<h3>Converted Paths</h3>"; print_a($this->pathList); @@ -3372,7 +3443,7 @@ TMPL; similar_text($text, html_entity_decode( $toForm, ENT_COMPAT, 'UTF-8'),$perc); $scoreStyle = ($perc > 98) ? 'label-success' : 'label-danger'; - echo "<h3><span class='label ".$scoreStyle."'>Score: ".number_format($perc)."%</span></h3>"; + echo "<h3><span class='label ".$scoreStyle."'>Similarity: ".number_format($perc)."%</span></h3>"; echo "<table class='table table-bordered'> @@ -3449,7 +3520,64 @@ return; // print_a($p); } - + + + /** + * Filters/Validates using the PHP5 filter_var() method. + * @param $text + * @param $type string str|int|email|url + * @return string | boolean + */ + function filter($text, $type='str',$validate=false) + { + if(empty($text)) + { + return $text; + } + + if($type == 'w') // words only. + { + return preg_replace('/[^\w]/',"",$text); + } + + if($type == 'wds') // words, digits and spaces only. + { + return preg_replace('/[^\w\d ]/',"",$text); + } + + + if($validate == false) + { + $filterTypes = array( + 'int' => FILTER_SANITIZE_NUMBER_INT, + 'str' => FILTER_SANITIZE_STRING, // no html. + 'email' => FILTER_SANITIZE_EMAIL, + 'url' => FILTER_SANITIZE_URL, + 'enc' => FILTER_SANITIZE_ENCODED + ); + } + else + { + $filterTypes = array( + 'int' => FILTER_VALIDATE_INT, + 'email' => FILTER_VALIDATE_EMAIL, + 'ip' => FILTER_VALIDATE_IP, + 'url' => FILTER_VALIDATE_URL, + + ); + } + + if(is_array($text)) + { + return filter_var_array($text, $filterTypes[$type]); + } + + + return filter_var($text, $filterTypes[$type]); + + } + + /** * Process and clean HTML from user input. * TODO Html5 tag support. @@ -3481,13 +3609,14 @@ return; $this->init(); } - if($checkPref) + if($this->scriptAccess === false) + { + $this->scriptAccess = e107::getConfig()->get('post_script', e_UC_MAINADMIN); // Pref to Allow <script> tags11; + } + + if(check_class($this->scriptAccess)) { - $post_scripts = e107::getConfig()->get('post_script', e_UC_MAINADMIN); // Pref to Allow <script> tags - if(check_class($post_scripts)) - { - $this->allowedTags = array_merge($this->allowedTags,$this->scriptTags); - } + $this->allowedTags = array_merge($this->allowedTags, $this->scriptTags); } @@ -3660,7 +3789,7 @@ return; /** * XSS HTML code to test against */ - private function getXss() + public function getXss() { $html = <<<EOF diff --git a/e107_handlers/theme_handler.php b/e107_handlers/theme_handler.php index e80fb0bee..f9a66cf1d 100644 --- a/e107_handlers/theme_handler.php +++ b/e107_handlers/theme_handler.php @@ -287,7 +287,7 @@ class themeHandler $themeArray[$file] = array_merge($themeArray[$file], $this->parse_theme_php($file)); } - if(count($themeArray[$file]['css']) > 1) + if(!empty($themeArray[$file]['css']) && count($themeArray[$file]['css']) > 1) { $themeArray[$file]['multipleStylesheets'] = TRUE; } diff --git a/e107_languages/English/lan_installer.php b/e107_languages/English/lan_installer.php index 644127b42..e06265157 100644 --- a/e107_languages/English/lan_installer.php +++ b/e107_languages/English/lan_installer.php @@ -53,7 +53,7 @@ define("LANINS_028", "Create Database?"); define("LANINS_029", "Table prefix:"); define("LANINS_030", "The MySQL server you would like e107 to use. It can also include a port number. e.g. “hostname:port” or a path to a local socket e.g. \":/path/to/socket\" for the localhost."); define("LANINS_031", "The username you wish e107 to use to connect to your MySQL server"); -define("LANINS_032", "The Password for the user you just entered"); +define("LANINS_032", "The Password for the user you just entered. Must not contain single or double quotes."); define("LANINS_033", "The MySQL database you wish e107 to reside in, sometimes referred to as a schema. Must begin with a letter. If the user has database create permissions you can opt to create the database automatically if it doesn't already exist."); define("LANINS_034", "The prefix you wish e107 to use when creating the e107 tables. Useful for multiple installs of e107 in one database schema."); define("LANINS_035", "Continue"); @@ -183,5 +183,6 @@ define("LANINS_124", "Please choose a password of at least 8 characters"); define("LANINS_125", "e107 has been installed successfully!"); define("LANINS_126", "For security reasons you should now set the file permissions on the e107_config.php file back to 644."); define("LANINS_127", "The database [x] already exists. Overwrite it? (any existing data will be lost)"); -define("LANINS_128", "Overwrite"); +define("LANINS_128", "Overwrite"); +define("LANINS_129", "Database not found."); diff --git a/install.php b/install.php index 10610329d..d2c324790 100644 --- a/install.php +++ b/install.php @@ -121,9 +121,9 @@ if($functions_ok == false) include_once("./{$HANDLERS_DIRECTORY}core_functions.php"); include_once("./{$HANDLERS_DIRECTORY}e107_class.php"); -function check_class($whatever) +function check_class($whatever='') { - return TRUE; + return true; } $override = array(); @@ -225,6 +225,8 @@ class e_install define('USERID', 1); define('USER', true); define('ADMIN', true); + + $tp = e107::getParser(); // session instance $this->session = e107::getSession(); @@ -245,6 +247,7 @@ class e_install if(isset($_POST['previous_steps'])) { $this->previous_steps = unserialize(base64_decode($_POST['previous_steps'])); + $this->previous_steps = $tp->toDB($this->previous_steps); unset($_POST['previous_steps']); } else @@ -252,7 +255,9 @@ class e_install $this->previous_steps = array(); } $this->get_lan_file(); - $this->post_data = $_POST; + $this->post_data = $tp->toDB($_POST); + + $this->template->SetTag('required', ''); if(isset($this->previous_steps['language'])) @@ -459,7 +464,7 @@ class e_install <tr> <td><label for='password'>".LANINS_026."</label></td> <td> - <input class='tbox' type='password' name='password' size='40' id='password' value='".varset($this->previous_steps['mysql']['password'])."' maxlength='100' {$isrequired} /> + <input class='tbox' type='password' name='password' size='40' id='password' value='".varset($this->previous_steps['mysql']['password'])."' maxlength='100' {$isrequired} pattern='[^\x22]+' /> <span class='field-help'>".LANINS_032."</span> </td> </tr> @@ -537,21 +542,21 @@ class e_install $this->template->SetTag("onload", "document.getElementById('name').focus()"); $this->template->SetTag("percent", 40); $this->template->SetTag("bartype", 'warning'); - + $tp = e107::getParser(); if(!empty($_POST['server'])) { - $this->previous_steps['mysql']['server'] = trim($_POST['server']); - $this->previous_steps['mysql']['user'] = trim($_POST['name']); - $this->previous_steps['mysql']['password'] = $_POST['password']; - $this->previous_steps['mysql']['db'] = trim($_POST['db']); - $this->previous_steps['mysql']['createdb'] = (isset($_POST['createdb']) && $_POST['createdb'] == TRUE ? TRUE : FALSE); - $this->previous_steps['mysql']['prefix'] = trim($_POST['prefix']); + $this->previous_steps['mysql']['server'] = trim($tp->filter($_POST['server'])); + $this->previous_steps['mysql']['user'] = trim($tp->filter($_POST['name'])); + $this->previous_steps['mysql']['password'] = trim($tp->filter($_POST['password'])); + $this->previous_steps['mysql']['db'] = trim($tp->filter($_POST['db'])); + $this->previous_steps['mysql']['createdb'] = (isset($_POST['createdb']) && $_POST['createdb'] == true ? true : false); + $this->previous_steps['mysql']['prefix'] = trim($tp->filter($_POST['prefix'])); } if(!empty($_POST['overwritedb'])) { - $this->previous_steps['mysql']['overwritedb'] = 1;; + $this->previous_steps['mysql']['overwritedb'] = 1; } $success = $this->check_name($this->previous_steps['mysql']['db'], FALSE) && $this->check_name($this->previous_steps['mysql']['prefix'], TRUE); @@ -622,6 +627,7 @@ class e_install if (!$res = @mysql_connect($this->previous_steps['mysql']['server'], $this->previous_steps['mysql']['user'], $this->previous_steps['mysql']['password'])) { $success = FALSE; + $e_forms->start_form("versions", $_SERVER['PHP_SELF'].($_SERVER['QUERY_STRING'] == "debug" ? "?debug" : "")); $page_content = LANINS_041.nl2br("\n\n<b>".LANINS_083."\n</b><i>".mysql_error()."</i>"); $alertType = 'error'; @@ -645,6 +651,7 @@ class e_install } else { + $e_forms->start_form("versions", $_SERVER['PHP_SELF'].($_SERVER['QUERY_STRING'] == "debug" ? "?debug" : "")); $page_content = "<i class='icon-ok'></i> ".LANINS_042; // @TODO Check database version here? /* @@ -685,26 +692,31 @@ class e_install if (!$this->dbqry($query)) { - $success = FALSE; - $page_content .= "<br /><br />".LANINS_043.nl2br("\n\n<b>".LANINS_083."\n</b><i>".mysql_error()."</i>"); + $success = false; + $alertType = 'error'; + $page_content .= "<br /><br />"; + $page_content .= (empty($this->previous_steps['mysql']['createdb'])) ? LANINS_129 : LANINS_043; + + + $page_content .= nl2br("\n\n<b>".LANINS_083."\n</b><i>".mysql_error()."</i>"); } else { $this->dbqry('SET NAMES `utf8`'); + $page_content .= $notification; // " } } if($success) { - $e_forms->start_form("versions", $_SERVER['PHP_SELF'].($_SERVER['QUERY_STRING'] == "debug" ? "?debug" : "")); + // $page_content .= "<br /><br />".LANINS_045."<br /><br />"; $this->add_button("submit", LANINS_035); $alertType = 'success'; } else { - $this->add_button("back", LANINS_035); } $head = $page_content; @@ -712,7 +724,9 @@ class e_install if ($success) $this->finish_form(); else + { $this->finish_form(3); + } $this->template->SetTag("stage_content", "<div class='alert alert-block alert-{$alertType}'>".$head."</div>".$e_forms->return_form()); $this->logLine('Stage 3 completed'); } @@ -941,6 +955,7 @@ class e_install private function stage_6() { global $e_forms; + $tp = e107::getParser(); $this->stage = 6; $this->logLine('Stage 6 started'); @@ -948,7 +963,7 @@ class e_install if(!vartrue($this->previous_steps['admin']['user']) || varset($_POST['u_name'])) { $_POST['u_name'] = str_replace(array("'", '"'), "", $_POST['u_name']); - $this->previous_steps['admin']['user'] = $_POST['u_name']; + $this->previous_steps['admin']['user'] = $tp->filter($_POST['u_name']); } if(!vartrue($this->previous_steps['admin']['display']) || varset($_POST['d_name'])) @@ -956,17 +971,17 @@ class e_install $_POST['d_name'] = str_replace(array("'", '"'), "", $_POST['d_name']); if ($_POST['d_name'] == "") { - $this->previous_steps['admin']['display'] = $_POST['u_name']; + $this->previous_steps['admin']['display'] = $tp->filter($_POST['u_name']); } else { - $this->previous_steps['admin']['display'] = $_POST['d_name']; + $this->previous_steps['admin']['display'] = $tp->filter($_POST['d_name']); } } if(!vartrue($this->previous_steps['admin']['email']) || varset($_POST['email'])) { - $this->previous_steps['admin']['email'] = $_POST['email']; + $this->previous_steps['admin']['email'] = $tp->filter($_POST['email'],'email'); } if(varset($_POST['pass1']) || !vartrue($this->previous_steps['admin']['password'])) @@ -1100,7 +1115,8 @@ class e_install private function stage_7() { global $e_forms; - + $tp = e107::getParser(); + $this->e107->e107_dirs['SYSTEM_DIRECTORY'] = str_replace("[hash]",$this->e107->site_path,$this->e107->e107_dirs['SYSTEM_DIRECTORY']); $this->e107->e107_dirs['CACHE_DIRECTORY'] = str_replace("[hash]",$this->e107->site_path,$this->e107->e107_dirs['CACHE_DIRECTORY']); $this->e107->e107_dirs['SYSTEM_DIRECTORY'] = str_replace("/".$this->e107->site_path,"",$this->e107->e107_dirs['SYSTEM_DIRECTORY']); @@ -1118,22 +1134,22 @@ class e_install if(varset($_POST['sitename'])) { - $this->previous_steps['prefs']['sitename'] = $_POST['sitename']; + $this->previous_steps['prefs']['sitename'] = $tp->filter($_POST['sitename']); } if(varset($_POST['sitetheme'])) { - $this->previous_steps['prefs']['sitetheme'] = $_POST['sitetheme']; + $this->previous_steps['prefs']['sitetheme'] = $tp->filter($_POST['sitetheme']); } if(varset($_POST['generate_content'])) { - $this->previous_steps['generate_content'] = $_POST['generate_content']; + $this->previous_steps['generate_content'] = $tp->filter($_POST['generate_content'],'int'); } if(varset($_POST['install_plugins'])) { - $this->previous_steps['install_plugins'] = $_POST['install_plugins']; + $this->previous_steps['install_plugins'] = $tp->filter($_POST['install_plugins'],'int'); } // Validate @@ -1782,7 +1798,7 @@ class e_install if(mysql_errno()) { $errorInfo = 'Query Error [#'.mysql_errno().']: '.mysql_error()."\nQuery: {$qry}"; - echo $errorInfo."<br />"; + // echo $errorInfo."<br />"; //exit; $this->debug_db_info['db_error_log'][] = $errorInfo; //$this->debug_db_info['db_log'][] = $qry;