View Issue Details

This bug affects 1 person(s).
 6
IDProjectCategoryView StatusLast Update
11682Bug reportsSurvey editingpublic2016-10-07 16:39
ReporterDenisChenu Assigned ToDenisChenu  
PrioritynoneSeverityminor 
Status closedResolutionfixed 
Product Version2.51.x 
Fixed in Version2.53 
Summary11682: Possible illegal string offset with some attribute
Description

Some Question attribute have an update during the LS history : for example the dualscale_headerA (and B) start without utf8, this was added after.

There are possible conflict then : DB have:

dualscale_headerA / language=null / value
dualscale_headerA / language=fr / another value

Steps To Reproduce

Hard to reproduce, because it's fixed when importing lss .... but adding at a question attribute with utf8 a value without language can be done via DB

Additional Information

It can happen each time we want a attribute to become utf8 : for example the em tip MUST be utf8 ....

TagsNo tags attached.
Attached Files
PHP warning.html (19,350 bytes)   
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>PHP warning</title>

<style type="text/css">
/*<![CDATA[*/
html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,font,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td{border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent;margin:0;padding:0;}
body{line-height:1;}
ol,ul{list-style:none;}
blockquote,q{quotes:none;}
blockquote:before,blockquote:after,q:before,q:after{content:none;}
:focus{outline:0;}
ins{text-decoration:none;}
del{text-decoration:line-through;}
table{border-collapse:collapse;border-spacing:0;}

body {
	font: normal 9pt "Verdana";
	color: #000;
	background: #fff;
}

h1 {
	font: normal 18pt "Verdana";
	color: #f00;
	margin-bottom: .5em;
}

h2 {
	font: normal 14pt "Verdana";
	color: #800000;
	margin-bottom: .5em;
}

h3 {
	font: bold 11pt "Verdana";
}

pre {
	font: normal 11pt Menlo, Consolas, "Lucida Console", Monospace;
}

pre span.error {
	display: block;
	background: #fce3e3;
}

pre span.ln {
	color: #999;
	padding-right: 0.5em;
	border-right: 1px solid #ccc;
}

pre span.error-ln {
	font-weight: bold;
}

.container {
	margin: 1em 4em;
}

.version {
	color: gray;
	font-size: 8pt;
	border-top: 1px solid #aaa;
	padding-top: 1em;
	margin-bottom: 1em;
}

.message {
	color: #000;
	padding: 1em;
	font-size: 11pt;
	background: #f3f3f3;
	-webkit-border-radius: 10px;
	-moz-border-radius: 10px;
	border-radius: 10px;
	margin-bottom: 1em;
	line-height: 160%;
}

.source {
	margin-bottom: 1em;
}

.code pre {
	background-color: #ffe;
	margin: 0.5em 0;
	padding: 0.5em;
	line-height: 125%;
	border: 1px solid #eee;
}

.source .file {
	margin-bottom: 1em;
	font-weight: bold;
}

.traces {
	margin: 2em 0;
}

.trace {
	margin: 0.5em 0;
	padding: 0.5em;
}

.trace.app {
	border: 1px dashed #c00;
}

.trace .number {
	text-align: right;
	width: 2em;
	padding: 0.5em;
}

.trace .content {
	padding: 0.5em;
}

.trace .plus,
.trace .minus {
	display:inline;
	vertical-align:middle;
	text-align:center;
	border:1px solid #000;
	color:#000;
	font-size:10px;
	line-height:10px;
	margin:0;
	padding:0 1px;
	width:10px;
	height:10px;
}

.trace.collapsed .minus,
.trace.expanded .plus,
.trace.collapsed pre {
	display: none;
}

.trace-file {
	cursor: pointer;
	padding: 0.2em;
}

.trace-file:hover {
	background: #f0ffff;
}
/*]]>*/
</style>
<style type="text/css">
:root .container > .infoBoxList > .shareInfoBox
{ display: none !important; }</style></head>

<body>
<div class="container">
	<h1>PHP warning</h1>

	<p class="message">
		Illegal string offset 'fr'	</p>

	<div class="source">
		<p class="file">/home/sondages.pro/htdocs/limesurvey_GIT/testing/masterall/application/models/Question.php(232)</p>
		<div class="code"><pre><span class="ln">220</span>         else
<span class="ln">221</span>         {
<span class="ln">222</span>             $aLanguages = array($sLanguage);
<span class="ln">223</span>         }
<span class="ln">224</span> 
<span class="ln">225</span>         if ($iQuestionID)
<span class="ln">226</span>         {
<span class="ln">227</span>             $oAttributeValues = QuestionAttribute::model()-&gt;findAll("qid=:qid",array('qid'=&gt;$iQuestionID));
<span class="ln">228</span>             $aAttributeValues=array();
<span class="ln">229</span>             foreach($oAttributeValues as $oAttributeValue)
<span class="ln">230</span>             {
<span class="ln">231</span>                 if($oAttributeValue-&gt;language){
<span class="error"><span class="ln error-ln">232</span>                     $aAttributeValues[$oAttributeValue-&gt;attribute][$oAttributeValue-&gt;language]=$oAttributeValue-&gt;value;
</span><span class="ln">233</span>                 }else{
<span class="ln">234</span>                     $aAttributeValues[$oAttributeValue-&gt;attribute]=$oAttributeValue-&gt;value;
<span class="ln">235</span>                 }
<span class="ln">236</span>             }
<span class="ln">237</span>         }
<span class="ln">238</span>         $aAttributeNames = \ls\helpers\questionHelper::getQuestionAttributesSettings($sQuestionType);
<span class="ln">239</span>         uasort($aAttributeNames, 'categorySort');
<span class="ln">240</span>         foreach ($aAttributeNames as $iKey =&gt; $aAttribute)
<span class="ln">241</span>         {
<span class="ln">242</span>             if ($aAttribute['i18n'] == false)
<span class="ln">243</span>             {
<span class="ln">244</span>                 if (isset($aAttributeValues[$aAttribute['name']]))
</pre></div>	</div>

	<div class="traces">
		<h2>Stack Trace</h2>
				<table style="width:100%;">
						<tbody><tr class="trace app expanded">
			<td class="number">
				#0			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/home/sondages.pro/htdocs/limesurvey_GIT/testing/masterall/application/controllers/admin/questions.php(82): <strong>Question</strong>-&gt;<strong>getAdvancedSettingsWithValues</strong>("174", "1", "44899", "fr")				</div>

				<div class="code"><pre><span class="ln">77</span>         $aData['surveyid'] = $iSurveyID;
<span class="ln">78</span>         $aData['qid'] = $qid;
<span class="ln">79</span>         $aData['gid'] = $gid;
<span class="ln">80</span>         $aData['qrrow'] = $qrrow;
<span class="ln">81</span>         $aData['baselang'] = $baselang;
<span class="error"><span class="ln error-ln">82</span>         $aAttributesWithValues = Question::model()-&gt;getAdvancedSettingsWithValues($qid, $qrrow['type'], $iSurveyID, $baselang);
</span><span class="ln">83</span>         $DisplayArray = array();
<span class="ln">84</span> 
<span class="ln">85</span>         foreach ($aAttributesWithValues as $aAttribute)
<span class="ln">86</span>         {
<span class="ln">87</span>             if (($aAttribute['i18n'] == false &amp;&amp; isset($aAttribute['value']) &amp;&amp; $aAttribute['value'] != $aAttribute['default']) || ($aAttribute['i18n'] == true &amp;&amp; isset($aAttribute['value'][$baselang]) &amp;&amp; $aAttribute['value'][$baselang] != $aAttribute['default']))
</pre></div>			</td>
		</tr>
						<tr class="trace core collapsed">
			<td class="number">
				#1			</td>
			<td class="content">
				<div class="trace-file">
										&nbsp;unknown(0): <strong>questions</strong>-&gt;<strong>view</strong>("44899", "41", "174")				</div>

							</td>
		</tr>
						<tr class="trace core collapsed">
			<td class="number">
				#2			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/home/sondages.pro/htdocs/limesurvey_GIT/testing/masterall/framework/web/actions/CAction.php(109): <strong>ReflectionMethod</strong>-&gt;<strong>invokeArgs</strong>(questions, array("44899", "41", "174"))				</div>

				<div class="code"><pre><span class="ln">104</span>             elseif($param-&gt;isDefaultValueAvailable())
<span class="ln">105</span>                 $ps[]=$param-&gt;getDefaultValue();
<span class="ln">106</span>             else
<span class="ln">107</span>                 return false;
<span class="ln">108</span>         }
<span class="error"><span class="ln error-ln">109</span>         $method-&gt;invokeArgs($object,$ps);
</span><span class="ln">110</span>         return true;
<span class="ln">111</span>     }
<span class="ln">112</span> }
</pre></div>			</td>
		</tr>
						<tr class="trace app expanded">
			<td class="number">
				#3			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/home/sondages.pro/htdocs/limesurvey_GIT/testing/masterall/application/core/Survey_Common_Action.php(101): <strong>CAction</strong>-&gt;<strong>runWithParamsInternal</strong>(questions, ReflectionMethod, array("surveyid" =&gt; "44899", "gid" =&gt; "41", "qid" =&gt; "174", "sa" =&gt; "view", ...))				</div>

				<div class="code"><pre><span class="ln">096</span>             $oMethod = new ReflectionMethod($this, $sDefault);
<span class="ln">097</span>         }
<span class="ln">098</span> 
<span class="ln">099</span>         // We're all good to go, let's execute it
<span class="ln">100</span>         // runWithParamsInternal would automatically get the parameters of the method and populate them as required with the params
<span class="error"><span class="ln error-ln">101</span>         return parent::runWithParamsInternal($this, $oMethod, $params);
</span><span class="ln">102</span>     }
<span class="ln">103</span> 
<span class="ln">104</span>     /**
<span class="ln">105</span>     * Some functions have different parameters, which are just an alias of the
<span class="ln">106</span>     * usual parameters we're getting in the url. This function just populates
</pre></div>			</td>
		</tr>
						<tr class="trace core collapsed">
			<td class="number">
				#4			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/home/sondages.pro/htdocs/limesurvey_GIT/testing/masterall/framework/web/CController.php(308): <strong>Survey_Common_Action</strong>-&gt;<strong>runWithParams</strong>(array("surveyid" =&gt; "44899", "gid" =&gt; "41", "qid" =&gt; "174", "sa" =&gt; "view"))				</div>

				<div class="code"><pre><span class="ln">303</span>     {
<span class="ln">304</span>         $priorAction=$this-&gt;_action;
<span class="ln">305</span>         $this-&gt;_action=$action;
<span class="ln">306</span>         if($this-&gt;beforeAction($action))
<span class="ln">307</span>         {
<span class="error"><span class="ln error-ln">308</span>             if($action-&gt;runWithParams($this-&gt;getActionParams())===false)
</span><span class="ln">309</span>                 $this-&gt;invalidActionParams($action);
<span class="ln">310</span>             else
<span class="ln">311</span>                 $this-&gt;afterAction($action);
<span class="ln">312</span>         }
<span class="ln">313</span>         $this-&gt;_action=$priorAction;
</pre></div>			</td>
		</tr>
						<tr class="trace core collapsed">
			<td class="number">
				#5			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/home/sondages.pro/htdocs/limesurvey_GIT/testing/masterall/framework/web/CController.php(286): <strong>CController</strong>-&gt;<strong>runAction</strong>(questions)				</div>

				<div class="code"><pre><span class="ln">281</span>      * @see runAction
<span class="ln">282</span>      */
<span class="ln">283</span>     public function runActionWithFilters($action,$filters)
<span class="ln">284</span>     {
<span class="ln">285</span>         if(empty($filters))
<span class="error"><span class="ln error-ln">286</span>             $this-&gt;runAction($action);
</span><span class="ln">287</span>         else
<span class="ln">288</span>         {
<span class="ln">289</span>             $priorAction=$this-&gt;_action;
<span class="ln">290</span>             $this-&gt;_action=$action;
<span class="ln">291</span>             CFilterChain::create($this,$action,$filters)-&gt;run();
</pre></div>			</td>
		</tr>
						<tr class="trace core collapsed">
			<td class="number">
				#6			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/home/sondages.pro/htdocs/limesurvey_GIT/testing/masterall/framework/web/CController.php(265): <strong>CController</strong>-&gt;<strong>runActionWithFilters</strong>(questions, array())				</div>

				<div class="code"><pre><span class="ln">260</span>         {
<span class="ln">261</span>             if(($parent=$this-&gt;getModule())===null)
<span class="ln">262</span>                 $parent=Yii::app();
<span class="ln">263</span>             if($parent-&gt;beforeControllerAction($this,$action))
<span class="ln">264</span>             {
<span class="error"><span class="ln error-ln">265</span>                 $this-&gt;runActionWithFilters($action,$this-&gt;filters());
</span><span class="ln">266</span>                 $parent-&gt;afterControllerAction($this,$action);
<span class="ln">267</span>             }
<span class="ln">268</span>         }
<span class="ln">269</span>         else
<span class="ln">270</span>             $this-&gt;missingAction($actionID);
</pre></div>			</td>
		</tr>
						<tr class="trace app expanded">
			<td class="number">
				#7			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/home/sondages.pro/htdocs/limesurvey_GIT/testing/masterall/application/controllers/AdminController.php(168): <strong>CController</strong>-&gt;<strong>run</strong>("questions")				</div>

				<div class="code"><pre><span class="ln">163</span>                     $this-&gt;redirect(array('/admin/authentication/sa/login'));
<span class="ln">164</span>                 }
<span class="ln">165</span> 
<span class="ln">166</span>             }
<span class="ln">167</span> 
<span class="error"><span class="ln error-ln">168</span>             return parent::run($action);
</span><span class="ln">169</span>     }
<span class="ln">170</span> 
<span class="ln">171</span>     /**
<span class="ln">172</span>     * Routes all the actions to their respective places
<span class="ln">173</span>     *
</pre></div>			</td>
		</tr>
						<tr class="trace core collapsed">
			<td class="number">
				#8			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/home/sondages.pro/htdocs/limesurvey_GIT/testing/masterall/framework/web/CWebApplication.php(282): <strong>AdminController</strong>-&gt;<strong>run</strong>("questions")				</div>

				<div class="code"><pre><span class="ln">277</span>         {
<span class="ln">278</span>             list($controller,$actionID)=$ca;
<span class="ln">279</span>             $oldController=$this-&gt;_controller;
<span class="ln">280</span>             $this-&gt;_controller=$controller;
<span class="ln">281</span>             $controller-&gt;init();
<span class="error"><span class="ln error-ln">282</span>             $controller-&gt;run($actionID);
</span><span class="ln">283</span>             $this-&gt;_controller=$oldController;
<span class="ln">284</span>         }
<span class="ln">285</span>         else
<span class="ln">286</span>             throw new CHttpException(404,Yii::t('yii','Unable to resolve the request "{route}".',
<span class="ln">287</span>                 array('{route}'=&gt;$route===''?$this-&gt;defaultController:$route)));
</pre></div>			</td>
		</tr>
						<tr class="trace core collapsed">
			<td class="number">
				#9			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/home/sondages.pro/htdocs/limesurvey_GIT/testing/masterall/framework/web/CWebApplication.php(141): <strong>CWebApplication</strong>-&gt;<strong>runController</strong>("admin/questions/sa/view")				</div>

				<div class="code"><pre><span class="ln">136</span>             foreach(array_splice($this-&gt;catchAllRequest,1) as $name=&gt;$value)
<span class="ln">137</span>                 $_GET[$name]=$value;
<span class="ln">138</span>         }
<span class="ln">139</span>         else
<span class="ln">140</span>             $route=$this-&gt;getUrlManager()-&gt;parseUrl($this-&gt;getRequest());
<span class="error"><span class="ln error-ln">141</span>         $this-&gt;runController($route);
</span><span class="ln">142</span>     }
<span class="ln">143</span> 
<span class="ln">144</span>     /**
<span class="ln">145</span>      * Registers the core application components.
<span class="ln">146</span>      * This method overrides the parent implementation by registering additional core components.
</pre></div>			</td>
		</tr>
						<tr class="trace core collapsed">
			<td class="number">
				#10			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/home/sondages.pro/htdocs/limesurvey_GIT/testing/masterall/framework/base/CApplication.php(185): <strong>CWebApplication</strong>-&gt;<strong>processRequest</strong>()				</div>

				<div class="code"><pre><span class="ln">180</span>     public function run()
<span class="ln">181</span>     {
<span class="ln">182</span>         if($this-&gt;hasEventHandler('onBeginRequest'))
<span class="ln">183</span>             $this-&gt;onBeginRequest(new CEvent($this));
<span class="ln">184</span>         register_shutdown_function(array($this,'end'),0,false);
<span class="error"><span class="ln error-ln">185</span>         $this-&gt;processRequest();
</span><span class="ln">186</span>         if($this-&gt;hasEventHandler('onEndRequest'))
<span class="ln">187</span>             $this-&gt;onEndRequest(new CEvent($this));
<span class="ln">188</span>     }
<span class="ln">189</span> 
<span class="ln">190</span>     /**
</pre></div>			</td>
		</tr>
						<tr class="trace app collapsed">
			<td class="number">
				#11			</td>
			<td class="content">
				<div class="trace-file">
											<div class="plus">+</div>
						<div class="minus">–</div>
										&nbsp;/home/sondages.pro/htdocs/limesurvey_GIT/testing/masterall/index.php(214): <strong>CApplication</strong>-&gt;<strong>run</strong>()				</div>

				<div class="code"><pre><span class="ln">209</span>         die (sprintf('%s should be writable by the webserver (766 or 776).', $sDefaultRuntimePath));
<span class="ln">210</span>     }
<span class="ln">211</span> }
<span class="ln">212</span> 
<span class="ln">213</span> Yii::$enableIncludePath = false;
<span class="error"><span class="ln error-ln">214</span> Yii::createApplication('LSYii_Application', $config)-&gt;run();
</span><span class="ln">215</span> 
<span class="ln">216</span> /* End of file index.php */
<span class="ln">217</span> /* Location: ./index.php */
</pre></div>			</td>
		</tr>
				</tbody></table>
	</div>

	<div class="version">
		2016-09-20 08:58:34 Apache/2.2.22 (Debian) <a href="http://www.yiiframework.com/">Yii Framework</a>/1.1.17	</div>
</div>

<script type="text/javascript">
/*<![CDATA[*/
var traceReg = new RegExp("(^|\\s)trace-file(\\s|$)");
var collapsedReg = new RegExp("(^|\\s)collapsed(\\s|$)");

var e = document.getElementsByTagName("div");
for(var j=0,len=e.length;j<len;j++){
	if(traceReg.test(e[j].className)){
		e[j].onclick = function(){
			var trace = this.parentNode.parentNode;
			if(collapsedReg.test(trace.className))
				trace.className = trace.className.replace("collapsed", "expanded");
			else
				trace.className = trace.className.replace("expanded", "collapsed");
		}
	}
}
/*]]>*/
</script>



</body></html>
PHP warning.html (19,350 bytes)   
Bug heat6
Complete LimeSurvey version number (& build)20160920
I will donate to the project if issue is resolvedNo
Browsernot relevant
Database type & versionnot relevant
Server OS (if known)not relevant
Webserver software & version (if known)not relevant
PHP Versionnot relevant

Relationships

related to 11683 closedDenisChenu Feature requests EM validations tip must be i18n 

Users monitoring this issue

There are no users monitoring this issue.

Activities

ollehar

ollehar

2016-09-20 10:20

administrator   ~40823

I get this error when I import the survey.

DenisChenu

DenisChenu

2016-09-20 10:26

developer   ~40824

? Maybe i deactivate debug when importing in my second GIT version ... I must test with https://github.com/LimeSurvey/LimeSurvey/pull/536/commits/1450e93dc200feca94f8b38fff16fd43895f72fd

DenisChenu

DenisChenu

2016-09-20 10:33

developer   ~40825

Last edited: 2016-09-20 10:33

Really strange : importing survey again, with last GIT : i lost the attribute, but no error ..... (without the fix)

DenisChenu

DenisChenu

2016-10-05 08:20

developer   ~41134

I have another issue : if NULL is after language value : attribute can not be updated.

But i dislike the $aAttributeValues[$oAttributeValue->attribute]['nolanguage'] system.

I think we must control if i18n is true or not before get the value.

DenisChenu

DenisChenu

2016-10-05 09:21

developer   ~41137

Fix committed to master branch: http://bugs.limesurvey.org/plugin.php?page=Source/view&amp;id=20824

DenisChenu

DenisChenu

2016-10-05 09:26

developer   ~41140

@Olle : tested import after fix : no issue for me (debug=2)

c_schmitz

c_schmitz

2016-10-07 16:39

administrator   ~41197

Version 2.54 released

Related Changesets

LimeSurvey: master 305cb4c6

2016-10-05 09:21:45

DenisChenu

Details Diff
Fixed issue 11682: Possible illegal string offset with some attribute
New feature 11683: i18n for EM validations tip
Dev: without loosing old value
Dev: fix extra value when save question, todo : add it to checkintegrity
Affected Issues
11682, 11683
mod - application/controllers/admin/database.php Diff File
mod - application/helpers/questionHelper.php Diff File
mod - application/models/Question.php Diff File
mod - application/models/QuestionAttribute.php Diff File

Issue History

Date Modified Username Field Change
2016-09-20 09:04 DenisChenu New Issue
2016-09-20 09:04 DenisChenu File Added: PHP warning.html
2016-09-20 09:04 DenisChenu File Added: limesurvey_survey_QuestionAttributeBadLanguage.lss
2016-09-20 10:06 DenisChenu Relationship added related to 11683
2016-09-20 10:13 DenisChenu Assigned To => DenisChenu
2016-09-20 10:13 DenisChenu Status new => assigned
2016-09-20 10:20 ollehar Note Added: 40823
2016-09-20 10:26 DenisChenu Note Added: 40824
2016-09-20 10:33 DenisChenu Note Added: 40825
2016-09-20 10:33 DenisChenu Note Edited: 40825
2016-10-05 08:20 DenisChenu Note Added: 41134
2016-10-05 09:21 DenisChenu Changeset attached => LimeSurvey master 305cb4c6
2016-10-05 09:21 DenisChenu Note Added: 41137
2016-10-05 09:21 DenisChenu Resolution open => fixed
2016-10-05 09:26 DenisChenu Status assigned => resolved
2016-10-05 09:26 DenisChenu Fixed in Version => 2.53
2016-10-05 09:26 DenisChenu Note Added: 41140
2016-10-07 16:39 c_schmitz Note Added: 41197
2016-10-07 16:39 c_schmitz Status resolved => closed
2019-11-01 17:25 c_schmitz Category Survey design => Survey editing