From: <gem...@li...> - 2013-04-17 15:47:03
|
Revision: 1236 http://sourceforge.net/p/gemstracker/code/1236 Author: matijsdejong Date: 2013-04-17 15:46:57 +0000 (Wed, 17 Apr 2013) Log Message: ----------- Robustness improvements with extra checks on field lengths and input validation Modified Paths: -------------- trunk/library/classes/Gems/Tracker/RespondentTrack.php trunk/library/classes/Gems/Tracker/Source/LimeSurvey1m9Database.php trunk/library/classes/Gems/Tracker/Token.php trunk/library/classes/Gems/User/UserLoader.php Modified: trunk/library/classes/Gems/Tracker/RespondentTrack.php =================================================================== --- trunk/library/classes/Gems/Tracker/RespondentTrack.php 2013-04-16 10:12:11 UTC (rev 1235) +++ trunk/library/classes/Gems/Tracker/RespondentTrack.php 2013-04-17 15:46:57 UTC (rev 1236) @@ -371,6 +371,11 @@ $this->_activeTokens[$token->getRoundId()] = $token; } + // Nothing to find + if (! $roundId) { + return null; + } + // Use array_key_exists since there may not be a valid round if (! array_key_exists($roundId, $this->_activeTokens)) { $tokenSelect = $this->tracker->getTokenSelect(); Modified: trunk/library/classes/Gems/Tracker/Source/LimeSurvey1m9Database.php =================================================================== --- trunk/library/classes/Gems/Tracker/Source/LimeSurvey1m9Database.php 2013-04-16 10:12:11 UTC (rev 1235) +++ trunk/library/classes/Gems/Tracker/Source/LimeSurvey1m9Database.php 2013-04-17 15:46:57 UTC (rev 1236) @@ -91,7 +91,14 @@ private $_languageMap; /** + * The default text length attribute fields should have. * + * @var int + */ + protected $attributeSize = 255; + + /** + * * @var Zend_Locale */ protected $locale; @@ -130,21 +137,25 @@ { $missingFields = array(); - $lengths = array(); - if (preg_match('/\(([^\)]+)\)/', $tokenTable['token']['Type'], $lengths)) { - $tokenLength = $lengths[1]; - } else { - $tokenLength = 0; - } + $tokenLength = $this->_extractFieldLength($tokenTable['token']['Type']); $token_library = $this->tracker->getTokenLibrary(); if ($tokenLength < $token_library->getLength()) { $tokenLength = $token_library->getLength(); - $missingFields['token'] = "CHANGE COLUMN `token` `token` varchar($tokenLength) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' NULL"; + $missingFields['token'] = 'CHANGE COLUMN `token` `token` varchar(' . $tokenLength . + ") CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' NULL"; } foreach ($this->_attributeMap as $name => $field) { if (! isset($tokenTable[$field])) { - $missingFields[$field] = "ADD $field varchar(255) CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'"; + $missingFields[$field] = 'ADD ' . $field . ' varchar(' . $this->attributeSize . + ") CHARACTER SET 'utf8' COLLATE 'utf8_general_ci'"; + } else { + $attrLength = $this->_extractFieldLength($tokenTable[$field]['Type']); + if ($attrLength < $this->attributeSize) { + $missingFields[$field] = "CHANGE COLUMN `$field` `$attrLength` varchar(" . + $this->attributeSize . + ") CHARACTER SET 'utf8' COLLATE 'utf8_general_ci' NULL"; + } } } @@ -152,6 +163,21 @@ } /** + * + * @param string $typeDescr E.g. int(11) or varchar(36) + * @return int In case 11 or 36 + */ + private function _extractFieldLength($typeDescr) + { + $lengths = array(); + if (preg_match('/\(([^\)]+)\)/', $typeDescr, $lengths)) { + return $lengths[1]; + } + + return 0; + } + + /** * Returns a list of field names that should be set in a newly inserted token. * * @param Gems_Tracker_Token $token @@ -159,10 +185,14 @@ */ protected function _fillAttributeMap(Gems_Tracker_Token $token) { - $values[$this->_attributeMap['respondentid']] = (string) $token->getRespondentId(); - $values[$this->_attributeMap['organizationid']] = (string) $token->getOrganizationId(); - $values[$this->_attributeMap['consentcode']] = (string) $token->getConsentCode(); - $values[$this->_attributeMap['resptrackid']] = (string) $token->getRespondentTrackId(); + $values[$this->_attributeMap['respondentid']] = + substr($token->getRespondentId(), 0, $this->attributeSize); + $values[$this->_attributeMap['organizationid']] = + substr($token->getOrganizationId(), 0, $this->attributeSize); + $values[$this->_attributeMap['consentcode']] = + substr($token->getConsentCode(), 0, $this->attributeSize); + $values[$this->_attributeMap['resptrackid']] = + substr($token->getRespondentTrackId(), 0, $this->attributeSize); return $values; } @@ -381,6 +411,7 @@ // SELECT sid, surveyls_title AS short_title, surveyls_description AS description, active, datestamp, ' . $this->_anonymizedField . ' $select = $lsDb->select(); + // 'alloweditaftercompletion' ? $select->from($this->_getSurveysTableName(), array('active', 'datestamp', 'tokenanswerspersistence', $this->_anonymizedField)) ->joinInner( $this->_getSurveyLanguagesTableName(), @@ -829,7 +860,7 @@ $sourceSurveyId = $this->_getSid($surveyId); } $select = $this->getRawTokenAnswerRowsSelect($filter, $surveyId, $sourceSurveyId); - + //Now process the filters $lsSurveyTable = $this->_getSurveyTableName($sourceSurveyId); $tokenField = $lsSurveyTable . '.token'; @@ -870,10 +901,10 @@ return array(); } - + /** * Returns the recordcount for a given filter - * + * * @param array $filter filter array * @param int $surveyId Gems Survey Id * @param string $sourceSurveyId Optional Survey Id used by source @@ -881,16 +912,16 @@ */ public function getRawTokenAnswerRowsCount(array $filter, $surveyId, $sourceSurveyId = null) { $select = $this->getRawTokenAnswerRowsSelect($filter, $surveyId, $sourceSurveyId); - + $p = new Zend_Paginator_Adapter_DbSelect($select); $count = $p->getCountSelect()->query()->fetchColumn(); - + return $count; } - + /** * Get the select object to use for RawTokenAnswerRows - * + * * @param array $filter * @param type $surveyId * @param type $sourceSurveyId @@ -937,7 +968,7 @@ // Add limit / offset to select and remove from filter $this->filterLimitOffset($filter, $select); - + foreach ($filter as $field => $values) { $field = $lsDb->quoteIdentifier($field); if (is_array($values)) { Modified: trunk/library/classes/Gems/Tracker/Token.php =================================================================== --- trunk/library/classes/Gems/Tracker/Token.php 2013-04-16 10:12:11 UTC (rev 1235) +++ trunk/library/classes/Gems/Tracker/Token.php 2013-04-17 15:46:57 UTC (rev 1236) @@ -125,7 +125,22 @@ protected $locale; /** + * The size of the result field, calculated from meta data when null, + * but can be set by project specific class to fixed value * + * @var int The maximum character length of the result field + */ + protected $resultFieldLength = null; + + /** + * Cache for storing the calculation of the length + * + * @var int the character length of the result field + */ + protected static $staticResultFieldLength = null; + + /** + * * @var Gems_Tracker_Survey */ protected $survey; @@ -213,6 +228,29 @@ } /** + * The maximum length of the result field + * + * @return int + */ + protected function _getResultFieldLength() + { + if (null !== $this->resultFieldLength) { + return $this->resultFieldLength; + } + + if (null !== self::$staticResultFieldLength) { + $this->resultFieldLength = self::$staticResultFieldLength; + return $this->resultFieldLength; + } + + $model = new MUtil_Model_TableModel('gems__tokens'); + self::$staticResultFieldLength = $model->get('gto_result', 'maxlength'); + $this->resultFieldLength = self::$staticResultFieldLength; + + return $this->resultFieldLength; + } + + /** * Update the token, both in the database and in memory. * * @param array $values The values that this token should be set to @@ -500,6 +538,11 @@ // not casting to strings means e.g. float results always result in // an update, even when they did not change. $values['gto_result'] = (string) $rawAnswers[$resultField]; + + // Chunk of text that is too long + if ($len = $this->_getResultFieldLength()) { + $values['gto_result'] = substr($values['gto_result'], 0, $len); + } } } } Modified: trunk/library/classes/Gems/User/UserLoader.php =================================================================== --- trunk/library/classes/Gems/User/UserLoader.php 2013-04-16 10:12:11 UTC (rev 1235) +++ trunk/library/classes/Gems/User/UserLoader.php 2013-04-17 15:46:57 UTC (rev 1236) @@ -518,7 +518,7 @@ return $this->loadUser(self::USER_PROJECT, $organization, $login_name); } - if ((null == $login_name) || (null == $organization)) { + if ((null == $login_name) || (null == $organization) || (! intval($organization))) { return $this->loadUser(self::USER_NOLOGIN, $organization, $login_name); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |