Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
93.75% covered (success)
93.75%
30 / 32
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
type_cast_helper
93.75% covered (success)
93.75%
30 / 32
50.00% covered (danger)
50.00%
1 / 2
13.04
0.00% covered (danger)
0.00%
0 / 1
 set_var
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
7
 recursive_set_var
88.89% covered (warning)
88.89%
16 / 18
0.00% covered (danger)
0.00%
0 / 1
6.05
1<?php
2/**
3*
4* This file is part of the phpBB Forum Software package.
5*
6* @copyright (c) phpBB Limited <https://www.phpbb.com>
7* @license GNU General Public License, version 2 (GPL-2.0)
8*
9* For full copyright and license information, please see
10* the docs/CREDITS.txt file.
11*
12*/
13
14namespace phpbb\request;
15
16/**
17* A helper class that provides convenience methods for type casting.
18*/
19class type_cast_helper implements \phpbb\request\type_cast_helper_interface
20{
21    /**
22    * Set variable $result to a particular type.
23    *
24    * @param mixed    &$result        The variable to fill
25    * @param mixed    $var            The contents to fill with
26    * @param mixed    $type            The variable type. Will be used with {@link settype()}
27    * @param bool    $multibyte        Indicates whether string values may contain UTF-8 characters.
28    *                                 Default is false, causing all bytes outside the ASCII range (0-127) to be replaced with question marks.
29    * @param bool    $trim            Indicates whether trim() should be applied to string values.
30    *                                 Default is true.
31    */
32    public function set_var(&$result, $var, $type, $multibyte = false, $trim = true)
33    {
34        settype($var, $type);
35        $result = $var;
36
37        if ($type == 'string')
38        {
39            $result = strtr($result, ["\r\n" => "\n", "\r" => "\n", "\0" => '', "\u{FEFF}" => '']);
40
41            if ($trim)
42            {
43                $result = trim($result);
44            }
45
46            $result = htmlspecialchars($result, ENT_COMPAT, 'UTF-8');
47
48            if ($multibyte)
49            {
50                $result = utf8_normalize_nfc($result);
51            }
52
53            if (!empty($result))
54            {
55                // Make sure multibyte characters are wellformed
56                if ($multibyte)
57                {
58                    if (!preg_match('//u', $result))
59                    {
60                        $result = '';
61                    }
62                }
63                else
64                {
65                    // no multibyte, allow only ASCII (0-127)
66                    $result = preg_replace('/[\x80-\xFF]/', '?', $result);
67                }
68            }
69        }
70    }
71
72    /**
73    * Recursively sets a variable to a given type using {@link set_var set_var}
74    *
75    * @param    mixed    $var        The value which shall be sanitised (passed by reference).
76    * @param    mixed    $default    Specifies the type $var shall have.
77    *                                 If it is an array and $var is not one, then an empty array is returned.
78    *                                 Otherwise var is cast to the same type, and if $default is an array all
79    *                                 keys and values are cast recursively using this function too.
80    * @param    bool    $multibyte    Indicates whether string keys and values may contain UTF-8 characters.
81    *                                 Default is false, causing all bytes outside the ASCII range (0-127) to
82    *                                 be replaced with question marks.
83    * @param    bool    $trim        Indicates whether trim() should be applied to string values.
84    *                                 Default is true.
85    */
86    public function recursive_set_var(&$var, $default, $multibyte, $trim = true)
87    {
88        if (is_array($var) !== is_array($default))
89        {
90            $var = (is_array($default)) ? array() : $default;
91            return;
92        }
93
94        if (!is_array($default))
95        {
96            $type = gettype($default);
97            $this->set_var($var, $var, $type, $multibyte, $trim);
98        }
99        else
100        {
101            // make sure there is at least one key/value pair to use get the
102            // types from
103            if (empty($default))
104            {
105                $var = array();
106                return;
107            }
108
109            $default_key = key($default);
110            $default_value = current($default);
111            $key_type = gettype($default_key);
112
113            $_var = $var;
114            $var = array();
115
116            foreach ($_var as $k => $v)
117            {
118                $this->set_var($k, $k, $key_type, $multibyte);
119
120                $this->recursive_set_var($v, $default_value, $multibyte, $trim);
121                $var[$k] = $v;
122            }
123        }
124    }
125}