From 1bf803c8447e413c4e1ac11055cbe7dea627107e Mon Sep 17 00:00:00 2001 From: Conrad Vermeulen Date: Fri, 13 Jul 2007 15:00:28 +0000 Subject: [PATCH] KTS-2178 "cross site scripting" Updated. --- lib/widgets/forms.inc.php | 244 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------------------------------------------------------------------------------------------------- 1 file changed, 122 insertions(+), 122 deletions(-) diff --git a/lib/widgets/forms.inc.php b/lib/widgets/forms.inc.php index a18fbd3..a552c8c 100644 --- a/lib/widgets/forms.inc.php +++ b/lib/widgets/forms.inc.php @@ -1,12 +1,12 @@ _context =& $context; // form identifier (namespace) - $this->sIdentifier = KTUtil::arrayGet($aOptions, 'identifier','kt.default'); + $this->sIdentifier = KTUtil::arrayGet($aOptions, 'identifier','kt.default'); // form name - $this->_kt_form_name = KTUtil::arrayGet($aOptions, '_kt_form_name', + $this->_kt_form_name = KTUtil::arrayGet($aOptions, '_kt_form_name', $this->generateFormName($this->sIdentifier), false); - + // form labelling $this->sLabel = KTUtil::arrayGet($aOptions, 'label'); $this->sDescription = KTUtil::arrayGet($aOptions, 'description'); - + // actions $this->_action = KTUtil::arrayGet($aOptions, 'action'); $qs = KTUtil::arrayGet($aOptions, 'actionparams',''); @@ -91,7 +91,7 @@ class KTForm { $this->_enctype="multipart/form-data"; } } - + $targeturl = KTUtil::arrayGet($aOptions, 'targeturl', false); if($targeturl === false) { $this->_actionurl = KTUtil::addQueryStringSelf($qs); @@ -114,43 +114,43 @@ class KTForm { } $this->_noframe = KTUtil::arrayGet($aOptions, 'noframe', false); - + // cancel // there are a few options here: // 1. cancel_action // 2. cancel_url $cancel_action = KTUtil::arrayGet($aOptions, 'cancel_action'); $cancel_url = KTUtil::arrayGet($aOptions, 'cancel_url'); - + if (!empty($cancel_action)) { - $this->bCancel = true; + $this->bCancel = true; // there are two cases here - if we have a context, we can // use the meldPersistQuery to create the url. if (!is_null($context)) { - $sQuery = $context->meldPersistQuery("", + $sQuery = $context->meldPersistQuery("", $cancel_action); - $this->_cancelurl = + $this->_cancelurl = KTUtil::addQueryString($_SERVER['PHP_SELF'], $sQuery); } else { // give it a try using addQSSelf $this->_cancelurl = KTUtil::addQueryStringSelf( - sprintf('%s=%s', $this->_event, $cancel_action)); + sprintf('%s=%s', $this->_event, $cancel_action)); } - - + + } else if (!empty($cancel_url)) { - $this->bCancel = true; + $this->bCancel = true; $this->_cancelurl = $cancel_url; } else { $this->bCancel = false; } - + // FIXME process extra arguments more intelligently $default_args = array(); if (!is_null($this->_context)) { $default_args = $this->_context->meldPersistQuery("","",true); } - $this->_extraargs = KTUtil::arrayGet($aOptions, + $this->_extraargs = KTUtil::arrayGet($aOptions, 'extraargs', $default_args); // method @@ -158,7 +158,7 @@ class KTForm { $this->_extraargs['postReceived'] = 1; } - + function getWidget(&$aInfo) { if (is_null($this->_oWF)) { $this->_oWF =& KTWidgetFactory::getSingleton(); @@ -167,13 +167,13 @@ class KTForm { if (is_null($aInfo)) { $widget = null; } else if (is_object($aInfo)) { - + // assume this is a fully configured object $widget =& $aInfo; } else { $namespaceOrObject = $aInfo[0]; $config = (array) $aInfo[1]; - + $widget =& $this->_oWF->get($namespaceOrObject, $config); } @@ -183,10 +183,10 @@ class KTForm { function getValidator($aInfo) { if (is_null($this->_oVF)) { $this->_oVF =& KTValidatorFactory::getSingleton(); - } - + } + $validator = null; - + // we don't want to expose the factory stuff to the user - its an // arbitrary distinction to the user. Good point from NBM ;) if (is_null($aInfo)) { @@ -197,29 +197,29 @@ class KTForm { } else { $namespaceOrObject = $aInfo[0]; $config = (array) $aInfo[1]; - + $validator =& $this->_oVF->get($namespaceOrObject, $config); } - + return $validator; } - + // set the "form widgets" that will be used. // these are pushed into the "data" component function setWidgets($aWidgets) { $this->_widgets = array(); - + if (is_null($this->_oWF)) { $this->_oWF =& KTWidgetFactory::getSingleton(); } - + $this->addWidgets($aWidgets); } - + function addWidgets($aWidgets) { - foreach ($aWidgets as $aInfo) { + foreach ($aWidgets as $aInfo) { $widget = $this->getWidget($aInfo); - + if (is_null($widget)) { continue; } else { @@ -227,51 +227,51 @@ class KTForm { } } } - + function setValidators($aValidators) { $this->_validators = array(); - + if (is_null($this->_oVF)) { $this->_oVF =& KTValidatorFactory::getSingleton(); - } - + } + $this->addValidators($aValidators); } - + function addValidators($aValidators) { // we don't want to expose the factory stuff to the user - its an // arbitrary distinction to the user. Good point from NBM ;) foreach ($aValidators as $aInfo) { $validator = $this->getValidator($aInfo); - + if (is_null($validator)) { continue; } else { $this->_validators[] = $validator; } - } + } } - + function addValidator($aInfo) { $validator = $this->getValidator($aInfo); - + if (is_null($validator)) { return false; } else { $this->_validators[] =& $validator; - } + } } - + function addWidget($aInfo) { $widget = $this->getWidget($aInfo); - + if (is_null($widget)) { return false; } else { $this->_widgets[] =& $widget; - } - } - + } + } + function addInitializedWidget($oWidget) { $this->_widgets[] = $oWidget; } @@ -279,10 +279,10 @@ class KTForm { function render() { $sWidgets = $this->renderWidgets(); $sButtons = $this->renderButtons(); - + return $this->renderContaining($sWidgets . ' ' . $sButtons); } - + function renderPage($sTitle = null, $sDescription = null) { if ($sTitle == null) { $sTitle = $this->sLabel; @@ -292,35 +292,35 @@ class KTForm { if (!is_null($sDescription)) { $sHelpText = sprintf('

%s

', $sDescription); } - return sprintf('

%s

%s %s', $sTitle, $sHelpText, $pageval); - } - + return sprintf('

%s

%s %s', sanitizeForHTML($sTitle), $sHelpText, $pageval); + } + function getErrors() { $aErrors = array(); - $old_data = KTUtil::arrayGet((array) $_SESSION['_kt_old_data'], + $old_data = KTUtil::arrayGet((array) $_SESSION['_kt_old_data'], $this->_kt_form_name, array()); if (KTUtil::arrayGet($old_data, 'identifier') == $this->sIdentifier) { $aErrors = (array) unserialize(KTUtil::arrayGet($old_data, 'errors')); - } + } return $aErrors; } - + function renderWidgets() { if (empty($this->_widgets)) { return ' '; } - + // do this all at the *last* possible moment // now we need to do two things: // - // 1. inform each "widget" that it needs to wrap itself inside + // 1. inform each "widget" that it needs to wrap itself inside // the "data" var - // 2. replace the widget's default values with the ones from the + // 2. replace the widget's default values with the ones from the // failed request, as appropriate. $bUseOld = false; $aOldData = array(); $aErrors = array(); - $old_data = KTUtil::arrayGet((array) $_SESSION['_kt_old_data'], + $old_data = KTUtil::arrayGet((array) $_SESSION['_kt_old_data'], $this->_kt_form_name, array()); if (KTUtil::arrayGet($old_data, 'identifier') == $this->sIdentifier) { $bUseOld = true; @@ -331,7 +331,7 @@ class KTForm { } $aErrors = (array) unserialize(KTUtil::arrayGet($old_data, 'errors')); } - + foreach ($this->_widgets as $k => $v) { if (PEAR::isError($v)) { continue; // error, handle it in render. @@ -339,16 +339,16 @@ class KTForm { $widget =& $this->_widgets[$k]; // reference needed since we're changing them $widget->wrapName('data'); if ($bUseOld) { - $widget->setDefault(KTUtil::arrayGet($aOldData, $widget->getBasename(), + $widget->setDefault(KTUtil::arrayGet($aOldData, $widget->getBasename(), $widget->getDefault(), false)); $widget->setErrors(KTUtil::arrayGet($aErrors, $widget->getBasename())); } } - + // too much overhead by half to use a template here // so we do it the "old fashioned" way. $rendered = array(); - + foreach ($this->_widgets as $v) { if (PEAR::isError($v)) { $rendered[] = sprintf(_kt('

Unable to show widget — %s

'), $v->getMessage()); @@ -356,45 +356,45 @@ class KTForm { $rendered[] = $v->render(); } } - + return implode(' ', $rendered); } - + function renderButtons() { $oKTTemplating =& KTTemplating::getSingleton(); $oTemplate = $oKTTemplating->loadTemplate('ktcore/forms/buttons'); - + // now do the render. $oTemplate->setData(array( - 'context' => &$this, + 'context' => &$this, )); - + return $oTemplate->render(); } - + function renderContaining() { - + $args = func_get_args(); $sInner = implode(' ', $args); - + $oKTTemplating =& KTTemplating::getSingleton(); $oTemplate = $oKTTemplating->loadTemplate('ktcore/forms/outerform'); - + // remove inner "action" var from extraargs // if its there at all. unset($this->_extraargs[$this->_event]); $this->_extraargs['_kt_form_name'] = $this->_kt_form_name; - + // now do the render. $oTemplate->setData(array( - 'context' => &$this, + 'context' => &$this, 'inner' => $sInner, )); - + return $oTemplate->render(); } - - function generateFormName($sIdentifier = null) { + + function generateFormName($sIdentifier = null) { if (!is_null($sIdentifier)) { // try use the existing one from the request. $existing = KTUtil::arrayGet($_REQUEST, '_kt_form_name'); @@ -409,62 +409,62 @@ class KTForm { } return KTUtil::randomString(32); // unique 32 char string } - + function validate() { // we first ask each widget to pull its data out. // while we do that, we create the storage set for the session // that widgets can call on later. - + $raw_data = KTUtil::arrayGet($_REQUEST, 'data'); $processed_data = array(); foreach ($this->_widgets as $oWidget) { if (PEAR::isError($oWidget)) { continue; } - - // widgets are expected to place their data in the "basename" + + // widgets are expected to place their data in the "basename" // entry in the processed data area // // they should also be able to reconstruct their inputs from this // since its what they get later. - + $res = $oWidget->process($raw_data); $processed_data = kt_array_merge($processed_data, $res); } - + // before we validate ANYTHING we store data into the session $store_data = array(); // we only want to store serialized values here foreach ($processed_data as $k => $v) { $store_data[$k] = serialize($v); } - + $_SESSION['_kt_old_data'][$this->_kt_form_name]['data'] = serialize($store_data); - $_SESSION['_kt_old_data'][$this->_kt_form_name]['identifier'] = - $this->sIdentifier; - $_SESSION['_kt_old_data'][$this->_kt_form_name]['created'] = + $_SESSION['_kt_old_data'][$this->_kt_form_name]['identifier'] = + $this->sIdentifier; + $_SESSION['_kt_old_data'][$this->_kt_form_name]['created'] = getCurrentDateTime(); - + $results = array(); $errors = array(); - + // some things can be checked by the actual widgets involved. These // are obvious (e.g. required) and shouldn't require the developer to // think about them. // // to accomplish this, we call each widget's "getValidators" method. - // + // // note that autovalidation can be turned off for a widget by passing // "autovalidate" => "false" in the widget's config. - + $extra_validators = array(); foreach ($this->_widgets as $oWidget) { - if (PEAR::isError($oWidget)) { + if (PEAR::isError($oWidget)) { continue; } - + $res = $oWidget->getValidators(); - + if (!is_null($res)) { if (is_array($res)) { $extra_validators = kt_array_merge($extra_validators, $res); @@ -473,23 +473,23 @@ class KTForm { } } } - + $validators = kt_array_merge($extra_validators, $this->_validators); - + foreach ($validators as $oValidator) { if (PEAR::isError($oValidator)) { // don't bother with broken validators, but warn the user/dev $errors['_kt_global'][] = $oValidator->getMessage(); - continue; + continue; } - + $res = $oValidator->validate($processed_data); - + // results comes out with a set of names and values. // these *shouldn't* overlap, so just merge them $extra_results = KTUtil::arrayGet($res, 'results', array()); $results = kt_array_merge($results, $extra_results); - + // errors *can* overlap // the format is: // basename => array(errors) @@ -501,27 +501,27 @@ class KTForm { $extra_errors = KTUtil::arrayGet($res, 'errors', array()); foreach ($extra_errors as $varname => $aErrors) { if (is_string($aErrors)) { - $errors[$varname][] = $aErrors; + $errors[$varname][] = $aErrors; } else { $errors[$varname] = kt_array_merge($errors[$varname], $aErrors); } } } - + $this->_errors = $errors; // store for later use without unserialising if (!empty($errors)) { - $_SESSION['_kt_old_data'][$this->_kt_form_name]['errors'] = + $_SESSION['_kt_old_data'][$this->_kt_form_name]['errors'] = serialize($errors); - } - + } + //var_dump($errors); exit(0); - + return array( 'errors' => $errors, 'results' => $results, ); } - + function handleError($sGlobalError = null, $aSimplerErrors = null) { if (!is_null($sGlobalError)) { $this->_errors['_kt_global'][] = $sGlobalError; @@ -531,23 +531,23 @@ class KTForm { $this->_errors[$k] = kt_array_merge($this->_errors[$k], $v); } // since we've changed them, update the stored version - $_SESSION['_kt_old_data'][$this->_kt_form_name]['errors'] = - serialize($this->_errors); + $_SESSION['_kt_old_data'][$this->_kt_form_name]['errors'] = + serialize($this->_errors); } if (is_array($this->_errors)) { $global_errors = KTUtil::arrayGet($this->_errors, '_kt_global', array()); $_SESSION['KTErrorMessage'] = kt_array_merge($_SESSION['KTErrorMessage'], $global_errors); } - + if (!empty($this->_failaction) && !is_null($this->_context)) { - $this->_context->errorRedirectTo($this->_failaction, - _kt("Please correct the errors indicated."), + $this->_context->errorRedirectTo($this->_failaction, + _kt("Please correct the errors indicated."), sprintf("_kt_form_name=%s",$this->_kt_form_name)); exit(0); } else if ($this->_failurl){ redirect(KTUtil::addQueryString($this->_failurl, - sprintf("_kt_form_name=%s",$this->_kt_form_name))); - exit(0); + sprintf("_kt_form_name=%s",$this->_kt_form_name))); + exit(0); } else { return '

' . _kt("An error occured, and no error handlers were configured.") . '

'; exit(0); -- libgit2 0.21.4