diff options
| -rw-r--r-- | HISTORY | 2 | ||||
| -rw-r--r-- | UPGRADE | 4 | ||||
| -rw-r--r-- | framework/Web/Javascripts/TJavaScript.php | 66 | ||||
| -rw-r--r-- | framework/Web/UI/ActiveControls/TCallbackClientSide.php | 3 | ||||
| -rw-r--r-- | framework/Web/UI/WebControls/TSlider.php | 6 | ||||
| -rw-r--r-- | framework/Web/UI/WebControls/TValidationSummary.php | 5 | ||||
| -rw-r--r-- | index.html | 4 | 
7 files changed, 61 insertions, 29 deletions
| @@ -67,6 +67,8 @@ BUG: Issue #381 - The property CausesValidation in the TActiveDatePicker not wor  BUG: Issue #382	- TJavaScript::quoteString() vulnerable to Unicode strings & TJavaScript::jsonEncode() doesn't check for errors (gabor)  BUG: Issue #383 - Some THttpRequest methods raise NOTICE level errors on missing headers (gabor)  BUG: Issue #388 - Output caching will raise error in Performance mode (gabor) +BUG: Issue #390 - TJavaScript::encode() float encoding depends on current locale (gabor) +BUG: Issue #391 - TJavaScript::encode() provides no simple way to pass strings in an XSS-safe way (gabor, ctrlaltca)  Version 3.1.10 Jul 17, 2011  BUG: Added missing timeout on TCacheHttpSession (ctrlaltca) @@ -45,7 +45,9 @@ Upgrading from v3.1.x  - Some TJavaScript methods have been modified to clear their use and provide better xss protection:    the undocumented quoteUTF8() was removed, since it didn't provide any real protection;    quoteString() now safely adds quotes around a string: previously it only added escape characters; -  the json* family of methods actually checks for errors and generate exceptions on fail. +  the json* family of methods actually checks for errors and generate exceptions on fail; +  strings beginning with "javascript:" doesn't bypass security checks in TJavascript::encode(), you need +  to explicitly use TJavascript::quoteFunction() to ensure raw javascript will be published.  - The php JSON extension is required; it ships by default with php 5.3 and is a lot faster that the old    TJSON-based implementation. TJSON has been removed, if you were calling it directly to encode/decode    you can switch to TJavaScript::jsonEncode(), TJavaScript::jsonDecode().     diff --git a/framework/Web/Javascripts/TJavaScript.php b/framework/Web/Javascripts/TJavaScript.php index 4f12eb94..ad120771 100644 --- a/framework/Web/Javascripts/TJavaScript.php +++ b/framework/Web/Javascripts/TJavaScript.php @@ -82,23 +82,24 @@ class TJavaScript  	}
  	/**
 -	 * @return string considers the string as raw javascript function code
 +	 * @return Marks a string as a javascript function. Once marke, the string is considered as a
 +	 * raw javascript function that is not supposed to be encoded by {@link encode}
  	 */
  	public static function quoteFunction($js)
  	{
 -		if(self::isFunction($js))
 +		if($js instanceof TJavaScriptFunction)
  			return $js;
  		else
 -			return 'javascript:'.$js;
 +			return new TJavaScriptFunction($js);
  	}
  	/**
 -	 * @return boolean true if string is raw javascript function code, i.e., if
 -	 * the string begins with <tt>javascript:</tt>
 +	 * @return boolean true if the parameter is marked as a javascript function, i.e. if it's considered as a
 +	 * raw javascript function that is not supposed to be encoded by {@link encode}
  	 */
  	public static function isFunction($js)
  	{
 -		return preg_match('/^\s*javascript:/i', $js);
 +		return ($js instanceof TJavaScriptFunction);
  	}
  	/**
 @@ -136,11 +137,7 @@ class TJavaScript  				if(($first==='[' && $last===']') || ($first==='{' && $last==='}'))
  					return $value;
  			}
 -			// if string begins with javascript: return the raw string minus the prefix
 -			if(self::isFunction($value))
 -				return preg_replace('/^\s*javascript:/', '', $value);
 -			else
 -				return self::quoteString($value);
 +			return self::quoteString($value);
  		}
  		else if(is_bool($value))
  			return $value?'true':'false';
 @@ -178,15 +175,28 @@ class TJavaScript  			return "$value";
  		else if(is_float($value))
  		{
 -			if($value===-INF)
 -				return 'Number.NEGATIVE_INFINITY';
 -			else if($value===INF)
 -				return 'Number.POSITIVE_INFINITY';
 -			else
 -				return "$value";
 +			switch($value)
 +			{
 +				case -INF:
 +					return 'Number.NEGATIVE_INFINITY';
 +					break;
 +				case INF:
 +					return 'Number.POSITIVE_INFINITY';
 +					break;
 +				default:
 +					$locale=localeConv();
 +					if($locale['decimal_point']=='.')
 +						return "$value";
 +					else
 +						return str_replace($locale['decimal_point'], '.', "$value");
 +					break;
 +			}
  		}
  		else if(is_object($value))
 -			return self::encode(get_object_vars($value),$toMap);
 +			if ($value instanceof TJavaScriptFunction)
 +				return preg_replace('/^\s*javascript:/', '', $value);
 +			else
 +				return self::encode(get_object_vars($value),$toMap);
  		else if($value===null)
  			return 'null';
  		else
 @@ -265,3 +275,23 @@ class TJavaScript  	}
  }
 +/**
 + * TJavaScriptFunction class that encloses string literals that are not 
 + * supposed to be escaped by TJavaScript::encode()
 + *
 + */
 +class TJavaScriptFunction
 +{
 +	private $_s;
 +
 +	public function __construct($s)
 +	{
 +		$this->_s = $s;
 +	}
 +
 +	public function __toString()
 +	{
 +		return $this->_s;
 +	}
 +}
 +
 diff --git a/framework/Web/UI/ActiveControls/TCallbackClientSide.php b/framework/Web/UI/ActiveControls/TCallbackClientSide.php index cfef37c4..54e6c1a3 100644 --- a/framework/Web/UI/ActiveControls/TCallbackClientSide.php +++ b/framework/Web/UI/ActiveControls/TCallbackClientSide.php @@ -54,8 +54,7 @@ class TCallbackClientSide extends TClientSideOptions  {
  	/**
  	 * Returns javascript statement enclosed within a javascript function.
 -	 * @param string javascript statement, if string begins within
 -	 * "javascript:" the whole string is assumed to be a function.
 +	 * @param string javascript statement
  	 * @return string javascript statement wrapped in a javascript function
  	 */
  	protected function ensureFunction($javascript)
 diff --git a/framework/Web/UI/WebControls/TSlider.php b/framework/Web/UI/WebControls/TSlider.php index da2189cb..f453e3ac 100644 --- a/framework/Web/UI/WebControls/TSlider.php +++ b/framework/Web/UI/WebControls/TSlider.php @@ -457,7 +457,7 @@ class TSlider extends TWebControl implements IPostBackDataHandler, IDataRenderer  		$options['axis'] = strtolower($this->getDirection());
  		$options['maximum'] = $maxValue;
  		$options['minimum'] = $minValue;
 -		$options['range'] = 'javascript:$R('.$minValue.",".$maxValue.")";
 +		$options['range'] = TJavascript::quoteFunction('$R('.$minValue.",".$maxValue.")");
  		$options['sliderValue'] = $this->getValue();
  		$options['disabled'] = !$this->getEnabled();
  		$values=$this->getValues();
 @@ -520,7 +520,7 @@ class TSliderClientScript extends TClientSideOptions  	 */
  	public function setOnChange($javascript)
  	{
 -		$code="javascript: function (value) { {$javascript} }";
 +		$code=TJavascript::quoteFunction("function (value) { {$javascript} }");
  		$this->setFunction('onChange', $code);
  	}
 @@ -537,7 +537,7 @@ class TSliderClientScript extends TClientSideOptions  	 */
  	public function setOnSlide($javascript)
  	{
 -		$code="javascript: function (value) { {$javascript} }";
 +		$code=TJavascript::quoteFunction("function (value) { {$javascript} }");
  		$this->setFunction('onSlide', $code);
  	}
 diff --git a/framework/Web/UI/WebControls/TValidationSummary.php b/framework/Web/UI/WebControls/TValidationSummary.php index 5f6a59ce..f3164d86 100644 --- a/framework/Web/UI/WebControls/TValidationSummary.php +++ b/framework/Web/UI/WebControls/TValidationSummary.php @@ -475,9 +475,8 @@ class TClientSideValidationSummaryOptions extends TClientSideOptions  	}
  	/**
 -	 * Ensure the string is a valid javascript function. If the string begins
 -	 * with "javascript:" valid javascript function is assumed, otherwise the
 -	 * code block is enclosed with "function(summary, validators){ }" block.
 +	 * Ensure the string is a valid javascript function. The code block
 +	 * is enclosed with "function(summary, validators){ }" block.
  	 * @param string javascript code.
  	 * @return string javascript function code.
  	 */
 @@ -28,10 +28,10 @@ Developers who have sufficient OOP experience will find PRADO is easy to learn a  <h2>Requirements</h2>  <p> -The sole requirement for PRADO is PHP 5.2.0 or higher. Please run <a href="requirements/index.php">requirement checker</a> to obtain more detailed requirement information. +The sole requirement for PRADO is PHP 5.3.3 or higher. Please run <a href="requirements/index.php">requirement checker</a> to obtain more detailed requirement information.  </p>  <p> -PRADO has been tested with Apache 2.2 on both Windows XP and RedHat Linux. +PRADO has been tested with Apache 2.2 on both Windows XP, various Linux flavours and Mac OSX.  </p>  <h2>Installation</h2> | 
