diff --git a/phpBB/includes/request/type_cast_helper.php b/phpBB/includes/request/type_cast_helper.php new file mode 100644 index 0000000000..ff392fbf8f --- /dev/null +++ b/phpBB/includes/request/type_cast_helper.php @@ -0,0 +1,178 @@ +=')) + { + $this->strip = false; + } + else + { + $this->strip = (@get_magic_quotes_gpc()) ? true : false; + } + } + + /** + * Recursively applies addslashes to a variable. + * + * @param mixed &$var Variable passed by reference to which slashes will be added. + */ + public function addslashes_recursively(&$var) + { + if (is_string($var)) + { + $var = addslashes($var); + } + else if (is_array($var)) + { + $var_copy = $var; + $var = array(); + foreach ($var_copy as $key => $value) + { + if (is_string($key)) + { + $key = addslashes($key); + } + $var[$key] = $value; + + $this->addslashes_recursively($var[$key]); + } + } + } + + /** + * Recursively applies addslashes to a variable if magic quotes are turned on. + * + * @param mixed &$var Variable passed by reference to which slashes will be added. + */ + public function add_magic_quotes(&$var) + { + if ($this->strip) + { + $this->addslashes_recursively($var); + } + } + + /** + * Set variable $result to a particular type. + * + * @param mixed &$result The variable to fill + * @param mixed $var The contents to fill with + * @param mixed $type The variable type. Will be used with {@link settype()} + * @param bool $multibyte Indicates whether string values may contain UTF-8 characters. + * Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks. + */ + public function set_var(&$result, $var, $type, $multibyte = false) + { + settype($var, $type); + $result = $var; + + if ($type == 'string') + { + $result = trim(htmlspecialchars(str_replace(array("\r\n", "\r", "\0"), array("\n", "\n", ''), $result), ENT_COMPAT, 'UTF-8')); + + if (!empty($result)) + { + // Make sure multibyte characters are wellformed + if ($multibyte) + { + if (!preg_match('/^./u', $result)) + { + $result = ''; + } + } + else + { + // no multibyte, allow only ASCII (0-127) + $result = preg_replace('/[\x80-\xFF]/', '?', $result); + } + } + + $result = ($this->strip) ? stripslashes($result) : $result; + } + } + + /** + * Recursively sets a variable to a given type using {@link set_var set_var} + * + * @param string $var The value which shall be sanitised (passed by reference). + * @param mixed $default Specifies the type $var shall have. + * If it is an array and $var is not one, then an empty array is returned. + * Otherwise var is cast to the same type, and if $default is an array all + * keys and values are cast recursively using this function too. + * @param bool $multibyte Indicates whether string keys and values may contain UTF-8 characters. + * Default is false, causing all bytes outside the ASCII range (0-127) to + * be replaced with question marks. + */ + public function recursive_set_var(&$var, $default, $multibyte) + { + if (is_array($var) !== is_array($default)) + { + $var = (is_array($default)) ? array() : $default; + return; + } + + if (!is_array($default)) + { + $type = gettype($default); + $this->set_var($var, $var, $type, $multibyte); + } + else + { + // make sure there is at least one key/value pair to use get the + // types from + if (empty($default)) + { + $var = array(); + return; + } + + list($default_key, $default_value) = each($default); + $value_type = gettype($default_value); + $key_type = gettype($default_key); + + $_var = $var; + $var = array(); + + foreach ($_var as $k => $v) + { + $this->set_var($k, $k, $key_type, $multibyte, $multibyte); + + $this->recursive_set_var($v, $default_value, $multibyte); + $this->set_var($var[$k], $v, $value_type, $multibyte); + } + } + } +} diff --git a/phpBB/includes/request/type_cast_helper_interface.php b/phpBB/includes/request/type_cast_helper_interface.php new file mode 100644 index 0000000000..96e984003c --- /dev/null +++ b/phpBB/includes/request/type_cast_helper_interface.php @@ -0,0 +1,63 @@ +type_cast_helper = new phpbb_type_cast_helper(); + } + + public function test_addslashes_recursively() + { + $data = array('some"string' => array('that"' => 'really"', 'needs"' => '"escaping')); + $expected = array('some\\"string' => array('that\\"' => 'really\\"', 'needs\\"' => '\\"escaping')); + + $this->type_cast_helper->addslashes_recursively($data); + + $this->assertEquals($expected, $data); + } +}