PluginProbe
Polylang / 3.8.10
Polylang v3.8.10
3.8.10 3.8.9 3.8.8 3.8.7 3.8.6 3.8.5 3.8.4 3.8.3 2.7 2.7.0.1 2.7.1 2.7.2 2.7.3 2.7.4 2.8 2.8.1 2.8.2 2.8.3 2.8.4 2.9 2.9.1 2.9.2 3.0 3.0.1 3.0.2 All 234 releases
← All changes | src/translatable-object.php +70 -0 3.8.5 → 3.8.10 View file →
@@ -125,8 +125,78 @@
125 125 'rewrite' => false,
126 126 '_pll' => true,
127 127 )
128 128 );
129 +
130 + $this->add_sanitization_hooks( $this->tax_language );
131 + }
132 +
133 + /**
134 + * Hooks sanitization for a Polylang taxonomy that stores serialized data in term descriptions.
135 + *
136 + * @since 3.8.10
137 + *
138 + * @param string $taxonomy Taxonomy name.
139 + * @return void
140 + *
141 + * @phpstan-param non-empty-string $taxonomy
142 + */
143 + protected function add_sanitization_hooks( string $taxonomy ): void {
144 + add_filter( "pre_{$taxonomy}_description", array( $this, 'sanitize_description' ), 0 );
145 + add_filter( "get_{$taxonomy}", array( $this, 'sanitize_term' ), 0 );
146 + }
147 +
148 + /**
149 + * Empties the description of a term hydrated from the database when it holds a disallowed serialized type.
150 + *
151 + * `get_{$taxonomy}` is fired by `get_term()`, whatever the sanitization context, and thus covers the
152 + * terms hydrated by `get_terms()` and `wp_get_object_terms()` too. Only the returned object is modified,
153 + * the stored value is left untouched.
154 + *
155 + * @since 3.8.10
156 + *
157 + * @param mixed $term Term object, may be anything another callback returned.
158 + * @return mixed The term, with a sanitized description.
159 + */
160 + public function sanitize_term( $term ) {
161 + if ( $term instanceof WP_Term && $this->has_disallowed_type( $term->description ) ) {
162 + $term->description = '';
163 + }
164 +
165 + return $term;
166 + }
167 +
168 + /**
169 + * Drops serialized values that contain a disallowed PHP type.
170 + *
171 + * @since 3.8.10
172 + *
173 + * @param mixed $description Term description.
174 + * @return string Empty string for a non-string value or when a disallowed type is found, unchanged otherwise.
175 + */
176 + public function sanitize_description( $description ) {
177 + if ( ! is_string( $description ) || '' === $description ) {
178 + return '';
179 + }
180 +
181 + return $this->has_disallowed_type( $description ) ? '' : $description;
182 + }
183 +
184 + /**
185 + * Tells if a serialized value contains a disallowed PHP type.
186 + *
187 + * The regex does not parse string payloads: a string value containing `{O:` or `";O:`
188 + * is treated as a disallowed type.
189 + *
190 + * Allowed serialized types: array, string, int, and bool.
191 + *
192 + * @since 3.8.10
193 + *
194 + * @param string $description Term description.
195 + * @return bool
196 + */
197 + private function has_disallowed_type( string $description ): bool {
198 + return 0 !== preg_match( '#(?:^|[;{])(?:[OCEdrR]:|N;)#', $description );
129 199 }
130 200
131 201 /**
132 202 * Returns the language taxonomy name.