diff --git a/main/UI/View/JsonPView.class.php b/main/UI/View/JsonPView.class.php new file mode 100644 index 0000000000..c6144ccc04 --- /dev/null +++ b/main/UI/View/JsonPView.class.php @@ -0,0 +1,75 @@ +toString(); + else + throw new WrongArgumentException('undefined type of callback, gived "'.gettype($callback).'"'); + + if(!preg_match(static::CALLBACK_PATTERN, $realCallbackName)) + throw new WrongArgumentException('invalid function name, you should set valid javascript function name! gived "'.$realCallbackName.'"'); + + $this->callback = $realCallbackName; + + return $this; + } + + /** + * @param Model $model + * @return string + */ + public function toString(/* Model */ $model = null) + { + Assert::isNotEmpty($this->callback, 'callback can not be empty!'); + + $json = parent::toString($model); + + return $this->callback.'('.$json.');'; + } + + } diff --git a/main/UI/View/JsonView.class.php b/main/UI/View/JsonView.class.php index 3df47ca817..83a8d6f788 100644 --- a/main/UI/View/JsonView.class.php +++ b/main/UI/View/JsonView.class.php @@ -12,7 +12,7 @@ /** * @ingroup Flow **/ - final class JsonView implements View, Stringable + class JsonView implements View, Stringable { protected $options = 0; diff --git a/main/UI/View/JsonXssView.class.php b/main/UI/View/JsonXssView.class.php new file mode 100644 index 0000000000..f0f7e59304 --- /dev/null +++ b/main/UI/View/JsonXssView.class.php @@ -0,0 +1,88 @@ +prefix = $value; + + return $this; + } + + /** + * @param Model $model + * @return string + */ + public function toString(/* Model */ $model = null) + { + /* + * Escaping warning datas + */ + $this->setHexAmp(true); + $this->setHexApos(true); + $this->setHexQuot(true); + $this->setHexTag(true); + + $json = JsonView::toString($model); + + $json = str_ireplace( + array('u0022', 'u0027'), + array('\u0022', '\u0027'), + $json + ); + + $result = ''."\n"; + + return $result; + } + + } diff --git a/test/main/JsonPViewTest.class.php b/test/main/JsonPViewTest.class.php new file mode 100644 index 0000000000..bee79ceb3d --- /dev/null +++ b/test/main/JsonPViewTest.class.php @@ -0,0 +1,99 @@ +',"'bar'",'"baz"','&blong&'); + + + public function testMain() + { + $model = Model::create()->set('array', $this->array); + $data = array('array' => $this->array); + $callback = 'myFunc'; + + //setup + $view = JsonPView::create(); + + try{ + // empty js callback function name + $view->toString($model); + + $this->fail('empty callback javascript function name expected!'); + } catch(WrongArgumentException $e) {} + + try{ + $view->setCallback('34_callback'); // invalid javascript function name + + $this->fail('invalid javascript function name expected!'); + } catch(WrongArgumentException $e) {} + + $view->setCallback($callback); + + $this->assertEquals($this->makeString($callback, $data), $view->toString($model) ); + + $simpleStringableObject = SimpleStringableObject::create()->setString($callback); + + $view->setCallback($simpleStringableObject); + + $this->assertEquals($this->makeString($callback, $data), $view->toString($model) ); + } + + /** + * @param $callback + * @param $data + * @return string + */ + protected function makeString($callback, $data) + { + return $callback.'('.json_encode( + $data + ).');'; + } + + } + + class SimpleStringableObject implements Stringable + { + protected $string = null; + + + /** + * @static + * @return SimpleStringableObject + */ + public static function create() + { + return new self(); + } + + /** + * @param $value + * @return SimpleStringableObject + */ + public function setString($value) + { + Assert::isString($value); + + $this->string = $value; + + return $this; + } + + /** + * @return str + */ + public function toString() + { + return $this->string; + } + } +?> \ No newline at end of file diff --git a/test/main/JsonXssViewTest.class.php b/test/main/JsonXssViewTest.class.php new file mode 100644 index 0000000000..0f8e77804b --- /dev/null +++ b/test/main/JsonXssViewTest.class.php @@ -0,0 +1,69 @@ +',"'bar'",'"baz"','&blong&'); + + public function testMain() + { + $prefix = 'window.'; + $callback = 'name'; + + $model = Model::create()->set('array', $this->array); + $data = array('array' => $this->array); + + //setup + $view = JsonXssView::create(); + + $defaultString = $view->toString($model); + + $this->assertEquals($defaultString, $this->makeString($prefix, $callback, $data) ); + + + $prefix='window2.'; + $callback='name2'; + + $view->setCallback($callback); + $view->setPrefix($prefix); + + $customString = $view->toString($model); + + $this->assertEquals($customString, $this->makeString($prefix, $callback, $data) ); + } + + /** + * @param $prefix + * @param $callback + * @return string + */ + protected function makeString($prefix, $callback, $data) + { + return ''."\n"; + } + + } + +?> \ No newline at end of file