diff --git a/_test/tests/inc/input.test.php b/_test/tests/inc/input.test.php index cec0b80f6fa417cbe6e3918479a1d62c0251994a..4a8fb8d7117665e21fa6e53909c33831c4439dc5 100644 --- a/_test/tests/inc/input.test.php +++ b/_test/tests/inc/input.test.php @@ -14,8 +14,58 @@ class input_test extends DokuWikiTest { 'empty' => '', 'emptya' => array(), 'do' => array('save' => 'Speichern'), + ); + /** + * custom filter function + * + * @param $string + * @return mixed + */ + public function myfilter($string) { + $string = str_replace('foo', 'bar', $string); + $string = str_replace('baz', '', $string); + return $string; + } + + public function test_filter() { + $_GET = array( + 'foo' => 'foo', + 'zstring'=> "foo\0bar", + 'znull' => "\0", + 'zint' => '42'."\0".'42', + 'zintbaz'=> "baz42", + ); + $_POST = $_GET; + $_REQUEST = $_GET; + $INPUT = new Input(); + + $filter = array($this,'myfilter'); + + $this->assertNotSame('foobar', $INPUT->str('zstring')); + $this->assertSame('foobar', $INPUT->filter()->str('zstring')); + $this->assertSame('bar', $INPUT->filter($filter)->str('foo')); + $this->assertSame('bar', $INPUT->filter()->str('znull', 'bar', true)); + $this->assertNotSame('foobar', $INPUT->str('zstring')); // make sure original input is unmodified + + $this->assertNotSame('foobar', $INPUT->get->str('zstring')); + $this->assertSame('foobar', $INPUT->get->filter()->str('zstring')); + $this->assertSame('bar', $INPUT->get->filter($filter)->str('foo')); + $this->assertSame('bar', $INPUT->get->filter()->str('znull', 'bar', true)); + $this->assertNotSame('foobar', $INPUT->get->str('zstring')); // make sure original input is unmodified + + $this->assertNotSame(4242, $INPUT->int('zint')); + $this->assertSame(4242, $INPUT->filter()->int('zint')); + $this->assertSame(42, $INPUT->filter($filter)->int('zintbaz')); + $this->assertSame(42, $INPUT->filter()->str('znull', 42, true)); + + $this->assertSame(true, $INPUT->bool('znull')); + $this->assertSame(false, $INPUT->filter()->bool('znull')); + + $this->assertSame('foobar', $INPUT->filter()->valid('zstring', array('foobar', 'bang'))); + } + public function test_str() { $_REQUEST = $this->data; $_POST = $this->data; diff --git a/inc/Input.class.php b/inc/Input.class.php index e7eef1c29cc0cae4c8ad540346cc4193678f8060..94da2a10efdc25af5a8d45f8e3c2309b5c1a287f 100644 --- a/inc/Input.class.php +++ b/inc/Input.class.php @@ -20,6 +20,11 @@ class Input { protected $access; + /** + * @var Callable + */ + protected $filter; + /** * Intilizes the Input class and it subcomponents */ @@ -30,6 +35,32 @@ class Input { $this->server = new ServerInput(); } + /** + * Apply the set filter to the given value + * + * @param string $data + * @return string + */ + protected function applyfilter($data){ + if(!$this->filter) return $data; + return call_user_func($this->filter, $data); + } + + /** + * Return a filtered copy of the input object + * + * Expects a callable that accepts one string parameter and returns a filtered string + * + * @param Callable|string $filter + * @return Input + */ + public function filter($filter='stripctl'){ + $this->filter = $filter; + $clone = clone $this; + $this->filter = ''; + return $clone; + } + /** * Check if a parameter was set * @@ -77,8 +108,9 @@ class Input { */ public function param($name, $default = null, $nonempty = false) { if(!isset($this->access[$name])) return $default; - if($nonempty && empty($this->access[$name])) return $default; - return $this->access[$name]; + $value = $this->applyfilter($this->access[$name]); + if($nonempty && empty($value)) return $default; + return $value; } /** @@ -121,10 +153,11 @@ class Input { public function int($name, $default = 0, $nonempty = false) { if(!isset($this->access[$name])) return $default; if(is_array($this->access[$name])) return $default; - if($this->access[$name] === '') return $default; - if($nonempty && empty($this->access[$name])) return $default; + $value = $this->applyfilter($this->access[$name]); + if($value === '') return $default; + if($nonempty && empty($value)) return $default; - return (int) $this->access[$name]; + return (int) $value; } /** @@ -138,9 +171,10 @@ class Input { public function str($name, $default = '', $nonempty = false) { if(!isset($this->access[$name])) return $default; if(is_array($this->access[$name])) return $default; - if($nonempty && empty($this->access[$name])) return $default; + $value = $this->applyfilter($this->access[$name]); + if($nonempty && empty($value)) return $default; - return (string) $this->access[$name]; + return (string) $value; } /** @@ -158,7 +192,8 @@ class Input { public function valid($name, $valids, $default = null) { if(!isset($this->access[$name])) return $default; if(is_array($this->access[$name])) return $default; // we don't allow arrays - $found = array_search($this->access[$name], $valids); + $value = $this->applyfilter($this->access[$name]); + $found = array_search($value, $valids); if($found !== false) return $valids[$found]; // return the valid value for type safety return $default; } @@ -176,10 +211,11 @@ class Input { public function bool($name, $default = false, $nonempty = false) { if(!isset($this->access[$name])) return $default; if(is_array($this->access[$name])) return $default; - if($this->access[$name] === '') return $default; - if($nonempty && empty($this->access[$name])) return $default; + $value = $this->applyfilter($this->access[$name]); + if($value === '') return $default; + if($nonempty && empty($value)) return $default; - return (bool) $this->access[$name]; + return (bool) $value; } /**