PluginProbe
Independent Analytics – WordPress Analytics Plugin / 2.14.0
Independent Analytics – WordPress Analytics Plugin v2.14.0
2.15.5 2.15.4 2.15.3 2.15.2 2.15.1 2.15.0 2.14.10 trunk 1.1 1.10 1.10.1 1.11 1.12 1.13 1.14 1.15 1.16 1.17 1.17.1 1.17.2 1.17.3 1.17.4 1.18 1.18.1 1.19.0 All 120 releases
independent-analytics / vendor / league / csv / src / EscapeFormula.php
EscapeFormula.php
143 lines 3.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * League.Csv (https://csv.thephpleague.com)
5 *
6 * (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11 declare (strict_types=1);
12 namespace IAWPSCOPED\League\Csv;
13
14 use InvalidArgumentException;
15 use function array_fill_keys;
16 use function array_keys;
17 use function array_map;
18 use function array_merge;
19 use function array_unique;
20 use function is_object;
21 use function is_string;
22 use function method_exists;
23 /**
24 * A Formatter to tackle CSV Formula Injection.
25 *
26 * @see http://georgemauer.net/2017/10/07/csv-injection.html
27 * @internal
28 */
29 class EscapeFormula
30 {
31 /**
32 * Spreadsheet formula starting character.
33 */
34 const FORMULA_STARTING_CHARS = ['=', '-', '+', '@', "\t", "\r"];
35 /**
36 * Effective Spreadsheet formula starting characters.
37 *
38 * @var array
39 */
40 protected $special_chars = [];
41 /**
42 * Escape character to escape each CSV formula field.
43 *
44 * @var string
45 */
46 protected $escape;
47 /**
48 * New instance.
49 *
50 * @param string $escape escape character to escape each CSV formula field
51 * @param string[] $special_chars additional spreadsheet formula starting characters
52 *
53 */
54 public function __construct(string $escape = "'", array $special_chars = [])
55 {
56 $this->escape = $escape;
57 if ([] !== $special_chars) {
58 $special_chars = $this->filterSpecialCharacters(...$special_chars);
59 }
60 $chars = array_unique(array_merge(self::FORMULA_STARTING_CHARS, $special_chars));
61 $this->special_chars = array_fill_keys($chars, 1);
62 }
63 /**
64 * Filter submitted special characters.
65 *
66 * @param string ...$characters
67 *
68 * @throws InvalidArgumentException if the string is not a single character
69 *
70 * @return string[]
71 */
72 protected function filterSpecialCharacters(string ...$characters) : array
73 {
74 foreach ($characters as $str) {
75 if (1 != \strlen($str)) {
76 throw new InvalidArgumentException('The submitted string ' . $str . ' must be a single character');
77 }
78 }
79 return $characters;
80 }
81 /**
82 * Returns the list of character the instance will escape.
83 *
84 * @return string[]
85 */
86 public function getSpecialCharacters() : array
87 {
88 return array_keys($this->special_chars);
89 }
90 /**
91 * Returns the escape character.
92 */
93 public function getEscape() : string
94 {
95 return $this->escape;
96 }
97 /**
98 * League CSV formatter hook.
99 *
100 * @see escapeRecord
101 */
102 public function __invoke(array $record) : array
103 {
104 return $this->escapeRecord($record);
105 }
106 /**
107 * Escape a CSV record.
108 */
109 public function escapeRecord(array $record) : array
110 {
111 return array_map([$this, 'escapeField'], $record);
112 }
113 /**
114 * Escape a CSV cell if its content is stringable.
115 *
116 * @param int|float|string|object|resource|array $cell the content of the cell
117 *
118 * @return mixed the escaped content
119 */
120 protected function escapeField($cell)
121 {
122 if (!is_string($cell) && (!is_object($cell) || !method_exists($cell, '__toString'))) {
123 return $cell;
124 }
125 $str_cell = (string) $cell;
126 if (isset($str_cell[0], $this->special_chars[$str_cell[0]])) {
127 return $this->escape . $str_cell;
128 }
129 return $cell;
130 }
131 /**
132 * @deprecated since 9.7.2 will be removed in the next major release
133 *
134 * Tells whether the submitted value is stringable.
135 *
136 * @param mixed $value value to check if it is stringable
137 */
138 protected function isStringable($value) : bool
139 {
140 return is_string($value) || is_object($value) && method_exists($value, '__toString');
141 }
142 }
143