PluginProbe
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More / 6.32
Formidable Forms – WordPress Form Builder for Contact Forms, Calculators, Quizzes & More v6.32
6.35 6.34 6.33.1 6.33 6.32.1 6.32 6.31 6.25 6.25.1 6.26 6.26.1 6.27 6.28 6.29 6.3 6.3.1 6.3.2 6.30 6.4 6.4.1 6.4.2 6.5 6.5.1 6.5.2 6.5.3 All 141 releases
← All changes | classes/helpers/FrmSerializedStringParserHelper.php +126 -42 6.36.32 View file →
@@ -37,76 +37,160 @@
37 37 * Parse a string containing a serialized data structure.
38 38 * This is the initial entry point into the recursive parser.
39 39 *
40 40 * @param string $string
41 + *
41 42 * @return mixed
42 43 */
43 44 public function parse( $string ) {
44 - return $this->do_parse( new FrmStringReaderHelper( $string ) );
45 + $unserialized_data = $this->do_parse( new FrmStringReaderHelper( $string ) );
46 +
47 + if ( is_array( $unserialized_data ) && $this->serialized_string_is_invalid( $string ) ) {
48 + return array_filter( $unserialized_data, array( $this, 'serialized_value_is_valid' ) );
49 + }
50 +
51 + return $unserialized_data;
45 52 }
46 53
47 54 /**
55 + * Check if an unserialized value is valid.
56 + *
57 + * @since 6.20
58 + *
59 + * @param mixed $value
60 + *
61 + * @return bool
62 + */
63 + private function serialized_value_is_valid( $value ) {
64 + return ! is_string( $value ) || ! str_contains( $value, ';s:' );
65 + }
66 +
67 + /**
68 + * @since 6.20
69 + *
70 + * @param string $string
71 + *
72 + * @return bool
73 + */
74 + private function serialized_string_is_invalid( $string ) {
75 + $invalid_substrings = array(
76 + ';s:10:\"a"',
77 + ';s:";',
78 + );
79 +
80 + foreach ( $invalid_substrings as $invalid ) {
81 + if ( str_contains( $string, $invalid ) ) {
82 + return true;
83 + }
84 + }
85 +
86 + return false;
87 + }
88 +
89 + /**
48 90 * This is the recursive parser.
49 91 *
50 92 * @param FrmStringReaderHelper $string
51 - * @return mixed
93 + *
94 + * @return array|bool|float|int|string|null
52 95 */
53 96 private function do_parse( $string ) {
54 - $val = null;
55 -
56 97 // May be : or ; as a terminator, depending on what the data type is.
57 - $type = substr( $string->read( 2 ), 0, 1 );
98 + $type = $string->read( 1 );
99 + $string->skip_next_character();
58 100
59 101 switch ( $type ) {
60 102 case 'a':
61 - // Associative array: a:length:{[index][value]...}
62 - $count = (int) $string->read_until( ':' );
103 + return $this->parse_array( $string );
63 104
64 - // Eat the opening "{" of the array.
65 - $string->read( 1 );
105 + case 's':
106 + return $this->parse_string( $string );
66 107
67 - $val = array();
68 - for ( $i = 0; $i < $count; $i++ ) {
69 - $array_key = $this->do_parse( $string );
70 - $array_value = $this->do_parse( $string );
108 + case 'i':
109 + return $this->parse_int( $string );
71 110
72 - if ( ! is_array( $array_key ) ) {
73 - $val[ $array_key ] = $array_value;
74 - }
75 - }
111 + case 'd':
112 + return $this->parse_float( $string );
76 113
77 - // Eat "}" terminating the array.
78 - $string->read( 1 );
79 - break;
114 + case 'b':
115 + return $this->parse_bool( $string );
116 + }
80 117
81 - case 's':
82 - $len = (int) $string->read_until( ':' );
83 - $val = $string->read( $len + 2 );
118 + // Includes case 'N' and case 'O'.
119 + // Treat a serialized object or anything unexpected as Null.
120 + return null;
121 + }
84 122
85 - // Eat the separator.
86 - $string->read( 1 );
87 - break;
123 + /**
124 + * @param FrmStringReaderHelper $string
125 + *
126 + * @return array
127 + */
128 + private function parse_array( $string ) {
129 + // Associative array: a:length:{[index][value]...}
130 + $count = (int) $string->read_until( ':' );
88 131
89 - case 'i':
90 - $val = (int) $string->read_until( ';' );
91 - break;
132 + // Eat the opening "{" of the array.
133 + $string->skip_next_character();
92 134
93 - case 'd':
94 - $val = (float) $string->read_until( ';' );
95 - break;
135 + $val = array();
96 136
97 - case 'b':
98 - // Boolean is 0 or 1.
99 - $bool = $string->read( 2 );
100 - $val = substr( $bool, 0, 1 ) == '1';
101 - break;
137 + for ( $i = 0; $i < $count; $i++ ) {
138 + $array_key = $this->do_parse( $string );
139 + $array_value = $this->do_parse( $string );
102 140
103 - default:
104 - // Includes case 'N' and case 'O'.
105 - // Treat a serialized object or anything unexpected as Null.
106 - $val = null;
107 - break;
141 + if ( ! is_array( $array_key ) ) {
142 + $val[ $array_key ] = $array_value;
143 + }
108 144 }
109 145
146 + // Eat "}" terminating the array.
147 + $string->skip_next_character();
148 +
149 + return $val;
150 + }
151 +
152 + /**
153 + * @param FrmStringReaderHelper $string
154 + *
155 + * @return string
156 + */
157 + private function parse_string( $string ) {
158 + $len = (int) $string->read_until( ':' );
159 + $val = $string->read( $len + 2 );
160 +
161 + // Eat the separator.
162 + $string->skip_next_character();
163 +
164 + return $val;
165 + }
166 +
167 + /**
168 + * @param FrmStringReaderHelper $string
169 + *
170 + * @return int
171 + */
172 + private function parse_int( $string ) {
173 + return (int) $string->read_until( ';' );
174 + }
175 +
176 + /**
177 + * @param FrmStringReaderHelper $string
178 + *
179 + * @return float
180 + */
181 + private function parse_float( $string ) {
182 + return (float) $string->read_until( ';' );
183 + }
184 +
185 + /**
186 + * @param FrmStringReaderHelper $string
187 + *
188 + * @return bool
189 + */
190 + private function parse_bool( $string ) {
191 + // Boolean is 0 or 1.
192 + $val = $string->read( 1 ) === '1';
193 + $string->skip_next_character();
110 194 return $val;
111 195 }
112 196 }