From d1a5be91129af293091e3e7deeeced6723b0ceb9 Mon Sep 17 00:00:00 2001 From: Thomas White Date: Thu, 25 Aug 2011 22:27:27 +0000 Subject: [PATCH] Tested all question types. Fixed PHP and JavaScript errors in all except for FileUpload and Date (part way done with Date) Modified ExpressionManager to properly use htmlspecialchars() where needed. git-svn-id: file:///Users/Shitiz/Downloads/lssvn/source/limesurvey_ci@10851 b72ed6b6-b9f8-46b5-92b4-906544132732 --- application/helpers/common_helper.php | 2 +- .../helpers/expressions/em_core_helper.php | 40 ++++++++++--------- .../helpers/expressions/em_manager_helper.php | 30 +++++++++----- application/helpers/frontend_helper.php | 8 ++-- application/helpers/qanda_helper.php | 36 ++++++++--------- application/libraries/Save.php | 2 +- 6 files changed, 66 insertions(+), 52 deletions(-) diff --git a/application/helpers/common_helper.php b/application/helpers/common_helper.php index 23dee22bca7..eb35390a6a4 100644 --- a/application/helpers/common_helper.php +++ b/application/helpers/common_helper.php @@ -2001,7 +2001,7 @@ function getextendedanswer($surveyid, $action, $fieldcode, $value, $format='') { $qidattributes = getQuestionAttributes($fields['qid']); $dateformatdetails = aGetDateFormatDataForQid($qidattributes, $surveyid); - $value = DateTime::createFromFormat("Y-m-d H:i:s", $value)->format($dateformatdetails['phpdate']); + $value=convertDateTimeFormat($value,"Y-m-d H:i:s",$dateformatdetails['phpdate']); } break; case "L": diff --git a/application/helpers/expressions/em_core_helper.php b/application/helpers/expressions/em_core_helper.php index 777c50579e6..e20e39e76fe 100644 --- a/application/helpers/expressions/em_core_helper.php +++ b/application/helpers/expressions/em_core_helper.php @@ -1139,7 +1139,7 @@ public function GetJavaScriptEquivalentOfExpression() { case 'DQ_STRING': case 'SQ_STRING': - $stringParts[] = "'" . addslashes($token[0]) . "'"; + $stringParts[] = "'" . htmlspecialchars($token[0],ENT_QUOTES,'UTF-8') . "'"; break; case 'SGQA': case 'WORD': @@ -1193,7 +1193,7 @@ public function GetJavaScriptEquivalentOfExpression() } else { - $stringParts[] = is_numeric($varInfo['codeValue']) ? $varInfo['codeValue'] : ("'" . addslashes($varInfo['codeValue']) . "'"); + $stringParts[] = is_numeric($varInfo['codeValue']) ? $varInfo['codeValue'] : ("'" . htmlspecialchars($varInfo['codeValue'],ENT_QUOTES,'UTF-8') . "'"); } } break; @@ -1202,7 +1202,7 @@ public function GetJavaScriptEquivalentOfExpression() $stringParts[] = $token[0]; break; case 'NUMBER': - $stringParts[] = is_numeric($token[0]) ? $token[0] : ("'" . addslashes($token[0]) . "'"); + $stringParts[] = is_numeric($token[0]) ? $token[0] : ("'" . $token[0] . "'"); break; case 'COMMA': $stringParts[] = $token[0] . ' '; @@ -1347,13 +1347,13 @@ public function GetPrettyPrintString() case 'DQ_STRING': // $messages[] = 'STRING'; $stringParts[] = "\""; - $stringParts[] = addslashes($token[0]); + $stringParts[] = htmlspecialchars($token[0],ENT_QUOTES,'UTF-8'); $stringParts[] = "\""; break; case 'SQ_STRING': // $messages[] = 'STRING'; $stringParts[] = "'"; - $stringParts[] = addslashes($token[0]); + $stringParts[] = htmlspecialchars($token[0],ENT_QUOTES,'UTF-8'); $stringParts[] = "'"; break; case 'SGQA': @@ -1381,7 +1381,7 @@ public function GetPrettyPrintString() $messages[] = $varInfo['jsName']; } if (strlen(trim($varInfo['codeValue'])) > 0) { - $messages[] = 'value=' . htmlspecialchars($varInfo['codeValue'],ENT_QUOTES); + $messages[] = 'value=' . htmlspecialchars($varInfo['codeValue'],ENT_QUOTES,'UTF-8'); } $stringParts[] = ""; $stringParts[] = $token[0]; @@ -1393,7 +1393,7 @@ public function GetPrettyPrintString() $messages[] = $varInfo['jsName']; } if (strlen(trim($varInfo['codeValue'])) > 0) { - $messages[] = 'value=' . htmlspecialchars($varInfo['codeValue'],ENT_QUOTES); + $messages[] = 'value=' . htmlspecialchars($varInfo['codeValue'],ENT_QUOTES,'UTF-8'); } $stringParts[] = ""; $stringParts[] = $token[0]; @@ -1724,7 +1724,7 @@ public function sProcessStringContainingExpressionsHelper($src, $questionNum) if (count($jsVarsUsed) > 0) { $idName = "LEMtailor_Q_" . $questionNum . "_" . $this->substitutionNum; - $resolvedParts[] = "" . $resolvedPart . ""; + $resolvedParts[] = "" . htmlspecialchars($resolvedPart,ENT_QUOTES,"UTF-8") . ""; $this->substitutionVars[$idName] = 1; $this->substitutionInfo[] = array( 'questionNum' => $questionNum, @@ -2165,7 +2165,7 @@ static function UnitTestEvaluator() 'ANSWER' => array('codeValue'=>'value for {ANSWER}', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), 'ASSESSMENTS' => array('codeValue'=>'value for {ASSESSMENTS}', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), 'ASSESSMENT_CURRENT_TOTAL' => array('codeValue'=>'value for {ASSESSMENT_CURRENT_TOTAL}', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), -'ASSESSMENT_HEADING' => array('codeValue'=>'value for {ASSESSMENT_HEADING}', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), +'ASSESSMENT_HEADING' => array('codeValue'=>'"Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), 'CHECKJAVASCRIPT' => array('codeValue'=>'value for {CHECKJAVASCRIPT}', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), 'CLEARALL' => array('codeValue'=>'value for {CLEARALL}', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), 'CLOSEWINDOW' => array('codeValue'=>'value for {CLOSEWINDOW}', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), @@ -2204,12 +2204,12 @@ static function UnitTestEvaluator() 'PRIVACY' => array('codeValue'=>'value for {PRIVACY}', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), 'QID' => array('codeValue'=>'value for {QID}', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), 'QUESTIONHELPPLAINTEXT' => array('codeValue'=>'value for {QUESTIONHELPPLAINTEXT}', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), -'QUESTIONHELP' => array('codeValue'=>'value for {QUESTIONHELP}', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), +'QUESTIONHELP' => array('codeValue'=>'"can single quoted strings" . \'contain nested \'quoted sections\'?', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), 'QUESTION_CLASS' => array('codeValue'=>'value for {QUESTION_CLASS}', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), 'QUESTION_CODE' => array('codeValue'=>'value for {QUESTION_CODE}', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), 'QUESTION_ESSENTIALS' => array('codeValue'=>'value for {QUESTION_ESSENTIALS}', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), 'QUESTION_FILE_VALID_MESSAGE' => array('codeValue'=>'value for {QUESTION_FILE_VALID_MESSAGE}', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), -'QUESTION_HELP' => array('codeValue'=>'value for {QUESTION_HELP}', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), +'QUESTION_HELP' => array('codeValue'=>'Can strings have embedded like , or even unbalanced "quotes or entities without terminal semicolons like & and <?', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), 'QUESTION_INPUT_ERROR_CLASS' => array('codeValue'=>'value for {QUESTION_INPUT_ERROR_CLASS}', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), 'QUESTION_MANDATORY' => array('codeValue'=>'value for {QUESTION_MANDATORY}', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), 'QUESTION_MAN_CLASS' => array('codeValue'=>'value for {QUESTION_MAN_CLASS}', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), @@ -2350,7 +2350,9 @@ static function UnitTestEvaluator() NULL~--b value for {INSERTANS:123X45X67}~INSERTANS:123X45X67 value for {QID}~QID -value for {ASSESSMENT_HEADING}~ASSESSMENT_HEADING +"Can strings contain embedded \"quoted passages\" (and parentheses + other characters?)?"~ASSESSMENT_HEADING +"can single quoted strings" . 'contain nested 'quoted sections'?~QUESTIONHELP +Can strings have embedded like , or even unbalanced "quotes or entities without terminal semicolons like & and <?~QUESTION_HELP value for {TOKEN:FIRSTNAME}~TOKEN:FIRSTNAME value for {THEREAREXQUESTIONS}~THEREAREXQUESTIONS 5~q5pointChoice.code @@ -2403,7 +2405,7 @@ static function UnitTestEvaluator() 5~strlen(hi) I love LimeSurvey~str_replace('like','love','I like LimeSurvey') 2~strpos('I like LimeSurvey','like') -Hi there!~d='Hi there!' +Hi there!~d='Hi there!' Hi there!~c=strip_tags(d) Hi there!~c +,-,*,/,!,,,and,&&,or,||,gt,>,lt,<,ge,>=,le,<=,eq,==,ne,!=~implode(',','+','-','*','/','!',',','and','&&','or','||','gt','>','lt','<','ge','>=','le','<=','eq','==','ne','!=') @@ -2479,8 +2481,7 @@ static function UnitTestEvaluator() $LEMalias2varName[] = "'" . $jsVarName . "':{'jsName':'" . $jsVarName . "'}"; $LEMvarNameAttr[] = "'" . $jsVarName . "': {" . "'jsName':'" . $jsVarName - . "','code':'" . $value - . "','shown':'" . $value + . "','code':'" . htmlspecialchars(preg_replace("/[[:space:]]/",' ',$value),ENT_QUOTES,'UTF-8') . "','question':'" . "','qid':'" . $i . "'}"; } @@ -2501,19 +2502,20 @@ static function UnitTestEvaluator() $resultStatus = 'ok'; $status = $em->Evaluate($expr); $result = $em->GetResult(); - $valToShow = $result; + $valToShow = htmlspecialchars($result,ENT_QUOTES,'UTF-8'); + $expectedToShow = htmlspecialchars($expectedResult,ENT_QUOTES,'UTF-8'); print ""; print "" . $em->GetPrettyPrintString() . "\n"; if (is_null($result)) { $valToShow = "NULL"; } print '' . $valToShow . "\n"; - if ($valToShow != $expectedResult) + if ($valToShow != $expectedToShow) { $resultStatus = 'error'; } - print "" . $expectedResult . "\n"; - print "" . $em->GetJavascriptTestforExpression($expectedResult) . " \n"; + print "" . $expectedToShow . "\n"; + print "" . $em->GetJavascriptTestforExpression($expectedToShow) . " \n"; $varsUsed = $em->GetVarsUsed(); if (is_array($varsUsed) and count($varsUsed) > 0) { $varDesc = array(); diff --git a/application/helpers/expressions/em_manager_helper.php b/application/helpers/expressions/em_manager_helper.php index ae1ac049634..d8cd660326d 100644 --- a/application/helpers/expressions/em_manager_helper.php +++ b/application/helpers/expressions/em_manager_helper.php @@ -300,7 +300,7 @@ public function setVariableAndTokenMappingsForExpressionManager($forceRefresh=fa $varNameAttr[$jsVarName] = "'" . $jsVarName . "':{" . "'jsName':'" . $jsVarName - . "','code':'" . $codeValue + . "','code':'" . htmlspecialchars(preg_replace('/[[:space:]]/',' ',$codeValue),ENT_QUOTES,'UTF-8') // . "','shown':'" . $displayValue // . "','question':'" . $question . "','qid':'" . $questionNum @@ -779,7 +779,7 @@ static function GetRelevanceAndTailoringJavaScript() foreach ($undeclaredJsVars as $jsVar) { // TODO - is different type needed for text? Or process value to striphtml? - $jsParts[] = "\n"; + $jsParts[] = "\n"; } } sort($qidList,SORT_NUMERIC); @@ -814,12 +814,12 @@ static function SetResetFunction($questionNum, $functionContents) static function UnitTestProcessStringContainingExpressions() { $vars = array( -'name' => array('codeValue'=>'Sergei', 'jsName'=>'java61764X1X1', 'readWrite'=>'Y', 'isOnCurrentPage'=>'Y'), +'name' => array('codeValue'=>'"\'', 'jsName'=>'java61764X1X1', 'readWrite'=>'Y', 'isOnCurrentPage'=>'Y'), 'age' => array('codeValue'=>45, 'jsName'=>'java61764X1X2', 'readWrite'=>'Y', 'isOnCurrentPage'=>'Y'), 'numKids' => array('codeValue'=>2, 'jsName'=>'java61764X1X3', 'readWrite'=>'Y', 'isOnCurrentPage'=>'Y'), 'numPets' => array('codeValue'=>1, 'jsName'=>'java61764X1X4', 'readWrite'=>'Y', 'isOnCurrentPage'=>'Y'), // Constants -'INSERTANS:61764X1X1' => array('codeValue'=> 'Sergei', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'Y'), +'INSERTANS:61764X1X1' => array('codeValue'=> '', 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'Y'), 'INSERTANS:61764X1X2' => array('codeValue'=> 45, 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'Y'), 'INSERTANS:61764X1X3' => array('codeValue'=> 2, 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), 'INSERTANS:61764X1X4' => array('codeValue'=> 1, 'jsName'=>'', 'readWrite'=>'N', 'isOnCurrentPage'=>'N'), @@ -867,20 +867,25 @@ static function UnitTestProcessStringContainingExpressions() $alltests[] = 'This line has a hidden script: '; $alltests[] = 'This line has a hidden script: '; + LimeExpressionManager::StartProcessingPage(); + LimeExpressionManager::StartProcessingGroup(1); + $lem = LimeExpressionManager::singleton(); $em = $lem->em; - $em->StartProcessingGroup(); - +// $em->StartProcessingGroup(); $em->RegisterVarnamesUsingMerge($vars); - print ''; + print '
TestResultVarName(jsName, readWrite, isOnCurrentPage)
'; // '; for ($i=0;$isProcessStringContainingExpressions($test,$i,2,1); - $prettyPrint = $em->GetLastPrettyPrintExpression(); + $result = LimeExpressionManager::ProcessString($test, $i, NULL, false, 1, 1); +// $result = $em->sProcessStringContainingExpressions($test,$i,2,1); + $prettyPrint = LimeExpressionManager::GetLastPrettyPrintExpression(); +// $prettyPrint = $em->GetLastPrettyPrintExpression(); print "\n"; print "\n"; + /* $varsUsed = $em->getAllVarsUsed(); if (is_array($varsUsed) and count($varsUsed) > 0) { $varDesc = array(); @@ -893,15 +898,22 @@ static function UnitTestProcessStringContainingExpressions() else { print "\n"; } + */ print "\n"; } print '
TestResult
VarName(jsName, readWrite, isOnCurrentPage)
" . $prettyPrint . "" . $result . " 
'; + LimeExpressionManager::FinishProcessingGroup(); + LimeExpressionManager::FinishProcessingPage(); + print LimeExpressionManager::GetRelevanceAndTailoringJavaScript(); } static function UnitTestRelevance() { // Tests: varName~relevance~inputType~message $tests = <<Here is the "junk" you entered: {junk} name~1~text~What is your name? age~1~text~How old are you? badage~1~expr~{badage=((age<16) || (age>80))} diff --git a/application/helpers/frontend_helper.php b/application/helpers/frontend_helper.php index dd10aa9d41e..22425e74316 100644 --- a/application/helpers/frontend_helper.php +++ b/application/helpers/frontend_helper.php @@ -930,13 +930,13 @@ function checkUploadedFileValidity($surveyid, $move, $backok=null) { if (isset($append) && $append) { - $filenotvalidated[$field."_file_".$i] .= sprintf($clang->gT("Sorry, only %s extensions are allowed !"),$validation['allowed_filetypes']); + $filenotvalidated[$field."_file_".$i] .= sprintf($clang->gT("Sorry, only %s extensions are allowed!"),$validation['allowed_filetypes']); unset($append); } else { $filenotvalidated = array(); - $filenotvalidated[$field."_file_".$i] .= sprintf($clang->gT("Sorry, only %s extensions are allowed !"),$validation['allowed_filetypes']); + $filenotvalidated[$field."_file_".$i] .= sprintf($clang->gT("Sorry, only %s extensions are allowed!"),$validation['allowed_filetypes']); } } } @@ -945,10 +945,10 @@ function checkUploadedFileValidity($surveyid, $move, $backok=null) else $filecount = 0; - if ($filecount < $validation['min_num_of_files']) + if (isset($validation['min_num_of_files']) && $filecount < $validation['min_num_of_files']) { $filenotvalidated = array(); - $filenotvalidated[$field] = $clang->gT("The minimum number of files have not been uploaded"); + $filenotvalidated[$field] = $clang->gT("The minimum number of files has not been uploaded."); } } } diff --git a/application/helpers/qanda_helper.php b/application/helpers/qanda_helper.php index b34ff1f13b0..2c3c51f2569 100644 --- a/application/helpers/qanda_helper.php +++ b/application/helpers/qanda_helper.php @@ -2056,7 +2056,7 @@ function do_date($ia) // Format the date for output if (trim($_SESSION[$ia[1]])!='') { - $dateoutput = DateTime::createFromFormat("Y-m-d H:i:s", $_SESSION[$ia[1]])->format($dateformatdetails['phpdate']); + $dateoutput = convertDateTimeFormat($_SESSION[$ia[1]], "Y-m-d H:i:s", $dateformatdetails['phpdate']); } else { @@ -2814,8 +2814,8 @@ function do_listwithcomment($ia) $answer .= '

- -"; + +'; $inputnames[]=$ia[1]; $inputnames[]=$ia[1].'comment'; } @@ -2870,7 +2870,7 @@ function do_listwithcomment($ia) $answer .= str_replace("\\", "", $_SESSION[$fname2]); } $answer .= ' - \n

\n"; +

'; $inputnames[]=$ia[1]; $inputnames[]=$ia[1].'comment'; } @@ -3013,7 +3013,7 @@ function do_ranking($ia) } $ranklist .= "\t \n"; $ranklist .= " 0) {$minanswscript .= "\tif (document.getElementById('answer".$myfname."').checked) { count += 1; }\n";} $answer_main .= "\n"; @@ -3850,7 +3848,6 @@ function do_multiplechoice_withcomments($ia) $answer_main .= "\t\n
\n\t\n"; - $inputnames[]=$myfname; $inputnames[]=$myfname2; } @@ -4041,10 +4038,7 @@ function do_file_upload($ia) returnTxt: '" . $clang->gT('Return to survey') . "' }; \n"; - if ($pos) - $answer .= ""; - else - $answer .= ""; + $answer .= ""; // Modal dialog $answer .= $uploadbutton; @@ -5786,7 +5780,8 @@ function do_array_yesnouncertain($ia) $qquery = "SELECT other FROM {$dbprefix}questions WHERE qid=".$ia[0]." AND language='".$_SESSION['s_lang']."'"; $qresult = db_execute_assoc($qquery); //Checked - $qrow = $qresult->result_array(); $other = $qrow['other']; + $qrow = $qresult->result_array(); + $other = isset($qrow['other']) ? $qrow['other'] : ''; $qidattributes=getQuestionAttributes($ia[0],$ia[4]); if (trim($qidattributes['answer_width'])!='') { @@ -7260,7 +7255,12 @@ function do_arraycolumns($ia) $odd_even = ''; foreach ($answers as $ld) { - $myfname = $ia[1].$ansrow['code']; + if (isset($ansrow['code'])) { + $myfname = $ia[1].$ansrow['code']; + } + else { + $myfname = $ia[1]; + } $trbc = alternation($trbc , 'row'); /* Check if this item has not been answered: the 'notanswered' variable must be an array, containing a list of unanswered questions, the current question must be in the array, diff --git a/application/libraries/Save.php b/application/libraries/Save.php index 0036669e522..5854f779b01 100644 --- a/application/libraries/Save.php +++ b/application/libraries/Save.php @@ -201,7 +201,7 @@ function run($args) { { $qidattributes = getQuestionAttributes($fieldexists['qid']); $dateformatdetails = aGetDateFormatDataForQid($qidattributes, $thissurvey); - $datetimeobj = new Date_Time_Converter($_SESSION[$value], $dateformatdetails['phpdate']); +// $datetimeobj = new Date_Time_Converter($_SESSION[$value], $dateformatdetails['phpdate']); $_SESSION[$value] = $CI->db->escape(date("Y-m-d H:i:s", strtotime($_SESSION[$value]))); } }