|
1
|
|
|
<?php |
|
2
|
|
|
// don't call the file directly |
|
3
|
|
|
defined( 'ABSPATH' ) or die(); |
|
4
|
|
|
|
|
5
|
|
|
class VaultPress_Hotfixes { |
|
6
|
|
|
function __construct() { |
|
7
|
|
|
global $wp_version; |
|
8
|
|
|
|
|
9
|
|
|
if ( version_compare( $wp_version, '3.0.2', '<' ) ) |
|
10
|
|
|
add_filter( 'query', array( $this, 'r16625' ) ); |
|
11
|
|
|
|
|
12
|
|
|
if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST && version_compare( $wp_version, '4.3.1', '<' ) ) |
|
13
|
|
|
add_action( 'xmlrpc_call', array( $this, 'filter_xmlrpc_methods' ) ); |
|
14
|
|
|
|
|
15
|
|
|
if ( version_compare( $wp_version, '3.3.2', '<' ) ) { |
|
16
|
|
|
add_filter( 'pre_kses', array( $this, 'r17172_wp_kses' ), 1, 3 ); |
|
17
|
|
|
add_filter( 'clean_url', array( $this, 'r17172_esc_url' ), 1, 3 ); |
|
18
|
|
|
} |
|
19
|
|
|
|
|
20
|
|
|
if ( version_compare( $wp_version, '3.1.3', '<' ) ) { |
|
21
|
|
|
add_filter( 'sanitize_file_name', array( $this, 'r17990' ) ); |
|
22
|
|
|
|
|
23
|
|
|
if ( ! empty( $_POST ) ) { |
|
24
|
|
|
$this->r17994( $_POST ); |
|
25
|
|
|
} |
|
26
|
|
|
// Protect add_meta, update_meta used by the XML-RPC API. |
|
27
|
|
|
add_filter( 'wp_xmlrpc_server_class', 'r17994_xmlrpc_server' ); |
|
28
|
|
|
|
|
29
|
|
|
// clean post_mime_type and guid (r17994) |
|
30
|
|
|
add_filter( 'pre_post_mime_type', array( $this, 'r17994_sanitize_mime_type' ) ); |
|
31
|
|
|
add_filter( 'post_mime_type', array( $this, 'r17994_sanitize_mime_type' ) ); |
|
32
|
|
|
add_filter( 'pre_post_guid', 'esc_url_raw' ); |
|
33
|
|
|
add_filter( 'post_guid', 'esc_url' ); |
|
34
|
|
|
} |
|
35
|
|
|
|
|
36
|
|
|
if ( version_compare( $wp_version, '3.1.4', '<' ) ) { |
|
37
|
|
|
add_filter( 'wp_insert_post_data', array( $this, 'r18368' ), 1, 2 ); |
|
38
|
|
|
|
|
39
|
|
|
// Add click jacking protection |
|
40
|
|
|
// login_init does not exist before 17826. |
|
41
|
|
|
$action = isset( $_REQUEST['action'] ) ? $_REQUEST['action'] : 'login'; |
|
42
|
|
|
add_action( 'login_form_' . $action, array( $this, 'r17826_send_frame_options_header' ), 10, 0 ); |
|
43
|
|
|
add_action( 'admin_init', array( $this, 'r17826_send_frame_options_header' ), 10, 0 ); |
|
44
|
|
|
|
|
45
|
|
|
add_filter( 'sanitize_option_WPLANG', array( $this, 'r18346_sanitize_lang_on_save' ) ); |
|
46
|
|
|
add_filter( 'sanitize_option_new_admin_email', array( $this, 'r18346_sanitize_admin_email_on_save' ) ); |
|
47
|
|
|
} |
|
48
|
|
|
add_filter( 'option_new_admin_email', array( $this, 'r18346_sanitize_admin_email' ) ); |
|
49
|
|
|
|
|
50
|
|
|
if ( version_compare( $wp_version, '3.3.2', '<' ) ) { |
|
51
|
|
|
remove_filter( 'comment_text', 'make_clickable' ); |
|
52
|
|
|
add_filter( 'comment_text', array( $this, 'r20493_make_clickable' ), 9 ); |
|
53
|
|
|
|
|
54
|
|
|
add_filter( 'comment_post_redirect', array( $this, 'r20486_comment_post_redirect' ) ); |
|
55
|
|
|
} |
|
56
|
|
|
|
|
57
|
|
|
// WooThemes < 3.8.3, foxypress, asset-manager, wordpress-member-private-conversation. |
|
58
|
|
|
$end_execution = false; |
|
59
|
|
|
if ( isset( $_SERVER['SCRIPT_FILENAME'] ) ) |
|
60
|
|
|
foreach ( array( 'preview-shortcode-external.php', 'uploadify.php', 'doupload.php', 'cef-upload.php', 'upload.php' ) as $vulnerable_script ) { |
|
61
|
|
|
if ( $vulnerable_script == basename( $_SERVER['SCRIPT_FILENAME'] ) ) { |
|
62
|
|
|
switch ( $vulnerable_script ) { |
|
63
|
|
|
case 'upload.php': |
|
64
|
|
|
$pma_config_file = realpath( dirname( $_SERVER['SCRIPT_FILENAME'] ) . DIRECTORY_SEPARATOR . 'paam-config-ajax.php' ); |
|
65
|
|
|
if ( false === $pma_config_file || ! in_array( $pma_config_file, get_included_files() ) ) { |
|
66
|
|
|
break; |
|
67
|
|
|
} |
|
68
|
|
|
default: |
|
69
|
|
|
$end_execution = true; |
|
70
|
|
|
break 2; |
|
71
|
|
|
} |
|
72
|
|
|
} |
|
73
|
|
|
} |
|
74
|
|
|
if ( $end_execution ) |
|
75
|
|
|
die( 'Disabled for security reasons' ); |
|
76
|
|
|
|
|
77
|
|
|
if ( version_compare( $wp_version, '3.3.2', '>') && version_compare( $wp_version, '3.4.1', '<' ) ) { |
|
78
|
|
|
add_filter( 'map_meta_cap', array( $this, 'r21138_xmlrpc_edit_posts' ), 10, 4 ); |
|
79
|
|
|
add_action( 'map_meta_cap', array( $this, 'r21152_unfiltered_html' ), 10, 4 ); |
|
80
|
|
|
} |
|
81
|
|
|
|
|
82
|
|
|
// https://core.trac.wordpress.org/changeset/21083 |
|
83
|
|
|
if ( version_compare( $wp_version, '3.3', '>=') && version_compare( $wp_version, '3.3.3', '<' ) ) |
|
84
|
|
|
add_filter( 'editable_slug', 'esc_textarea' ); |
|
85
|
|
|
|
|
86
|
|
|
if ( version_compare( $wp_version, '4.1', '>=' ) && version_compare( $wp_version, '4.1.2', '<' ) ) |
|
87
|
|
|
add_filter( 'wp_check_filetype_and_ext', array( $this, 'wp_check_filetype_and_ext' ), 20, 4 ); |
|
88
|
|
|
|
|
89
|
|
|
if ( version_compare( $wp_version, '4.2', '<=' ) ) |
|
90
|
|
|
add_filter( 'preprocess_comment', array( $this, 'filter_long_comment_xss' ), 10, 1 ); |
|
91
|
|
|
|
|
92
|
|
|
add_filter( 'get_pagenum_link', array( $this, 'get_pagenum_link' ) ); |
|
93
|
|
|
|
|
94
|
|
|
add_filter( 'jetpack_xmlrpc_methods', array( $this, 'disable_jetpack_xmlrpc_methods_293' ), 20, 3 ); |
|
95
|
|
|
add_filter( 'xmlrpc_methods', array( $this, 'disable_xmlrpc_methods_293' ), 20 ); |
|
96
|
|
|
|
|
97
|
|
|
// Protect All-in-one SEO from non-authorized users making changes, and script injection attacks. |
|
98
|
|
|
add_action( 'wp_ajax_aioseop_ajax_save_meta', array( $this, 'protect_aioseo_ajax' ), 1 ); |
|
99
|
|
|
|
|
100
|
|
|
// Protect The MailPoet plugin (wysija-newsletters) from remote file upload. Affects versions <= 2.6.6 |
|
101
|
|
|
add_action( 'admin_init', array( $this , 'protect_wysija_newsletters_verify_capability' ), 1 ); |
|
102
|
|
|
|
|
103
|
|
|
// Protect the Revolution Slider plugin (revslider) from local file inclusion. Affects versions < 4.2 |
|
104
|
|
|
add_action( 'init', array( $this , 'protect_revslider_lfi' ), 1 ); |
|
105
|
|
|
|
|
106
|
|
|
// Protect WooCommerce from object injection via PayPal IPN notifications. Affects 2.0.20 -> 2.3.10 |
|
107
|
|
|
add_action( 'init', array( $this , 'protect_woocommerce_paypal_object_injection' ), 1 ); |
|
108
|
|
|
|
|
109
|
|
|
// Protect Jetpack from comments-based XSS attack |
|
110
|
|
|
add_action( 'plugins_loaded', array( $this, 'protect_jetpack_402_from_oembed_xss' ), 1 ); |
|
111
|
|
|
|
|
112
|
|
|
if ( version_compare( $wp_version, '3.1', '>=') && version_compare( $wp_version, '4.3', '<=' ) ) { |
|
113
|
|
|
if ( is_admin() ) { |
|
114
|
|
|
add_filter( 'user_email', array( $this, 'patch_user_email' ), 10 , 3 ); |
|
115
|
|
|
} |
|
116
|
|
|
|
|
117
|
|
|
remove_shortcode( 'wp_caption' ); |
|
118
|
|
|
remove_shortcode( 'caption' ); |
|
119
|
|
|
add_shortcode( 'wp_caption', array( $this, 'filtered_caption_shortcode' ) ); |
|
120
|
|
|
add_shortcode( 'caption', array( $this, 'filtered_caption_shortcode' ) ); |
|
121
|
|
|
} |
|
122
|
|
|
|
|
123
|
|
|
// Protect Akismet < 3.1.5 from stored XSS in admin page |
|
124
|
|
|
add_filter( 'init', array( $this, 'protect_akismet_comment_xss' ), 50 ); |
|
125
|
|
|
|
|
126
|
|
|
if ( version_compare( $wp_version, '4.7.1', '<=' ) ) { |
|
127
|
|
|
// Protect WordPress 4.4 - 4.7.1 against WP REST type abuse |
|
128
|
|
|
if ( version_compare( $wp_version, '4.4', '>=' ) ) { |
|
129
|
|
|
add_filter( 'rest_pre_dispatch', array( $this, 'protect_rest_type_juggling' ), 10, 3 ); |
|
130
|
|
|
} |
|
131
|
|
|
|
|
132
|
|
|
// Protect WordPress 4.0 - 4.7.1 against faulty youtube embeds |
|
133
|
|
|
if ( version_compare( $wp_version, '4.0', '>=' ) ) { |
|
134
|
|
|
$this->protect_youtube_embeds(); |
|
135
|
|
|
} |
|
136
|
|
|
} |
|
137
|
|
|
|
|
138
|
|
|
} |
|
139
|
|
|
|
|
140
|
|
|
function protect_rest_type_juggling( $replace, $server, $request ) { |
|
141
|
|
|
if ( isset( $request['id'] ) ) { |
|
142
|
|
|
$request['id'] = intval( $request['id'] ); |
|
143
|
|
|
} |
|
144
|
|
|
|
|
145
|
|
|
return $replace; |
|
146
|
|
|
} |
|
147
|
|
|
|
|
148
|
|
|
function protect_youtube_embeds() { |
|
149
|
|
|
if ( ! apply_filters( 'load_default_embeds', true ) ) { |
|
150
|
|
|
return; |
|
151
|
|
|
} |
|
152
|
|
|
|
|
153
|
|
|
wp_embed_unregister_handler( 'youtube_embed_url' ); |
|
154
|
|
|
wp_embed_register_handler( 'youtube_embed_url', '#https?://(www.)?youtube\.com/(?:v|embed)/([^/]+)#i', array( $this, 'safe_embed_handler_youtube' ), 9, 4 ); |
|
155
|
|
|
} |
|
156
|
|
|
|
|
157
|
|
|
function safe_embed_handler_youtube( $matches, $attr, $url, $rawattr ) { |
|
158
|
|
|
$matches[2] = urlencode( $matches[2] ); |
|
159
|
|
|
return( wp_embed_handler_youtube( $matches, $attr, $url, $rawattr ) ); |
|
160
|
|
|
} |
|
161
|
|
|
|
|
162
|
|
|
function protect_jetpack_402_from_oembed_xss() { |
|
163
|
|
|
if ( $this->needs_jetpack_402_fix() ) { |
|
164
|
|
|
add_filter( 'jetpack_comments_allow_oembed', array( $this, 'disable_jetpack_oembed' ) ); |
|
165
|
|
|
} |
|
166
|
|
|
} |
|
167
|
|
|
|
|
168
|
|
|
function needs_jetpack_402_fix() { |
|
169
|
|
|
if ( ! defined( 'JETPACK__VERSION' ) ) { |
|
170
|
|
|
return false; |
|
171
|
|
|
} |
|
172
|
|
|
|
|
173
|
|
|
if ( version_compare( JETPACK__VERSION, '2.0.7', '<' ) ) { |
|
174
|
|
|
return true; |
|
175
|
|
|
} |
|
176
|
|
|
|
|
177
|
|
|
if ( version_compare( JETPACK__VERSION, '4.0.2', '>' ) ) { |
|
178
|
|
|
return false; |
|
179
|
|
|
} |
|
180
|
|
|
|
|
181
|
|
|
$secure_jetpacks = array( |
|
182
|
|
|
'2.1' => '2.1.5', |
|
183
|
|
|
'2.2' => '2.2.8', |
|
184
|
|
|
'2.3' => '2.3.8', |
|
185
|
|
|
'2.4' => '2.4.5', |
|
186
|
|
|
'2.5' => '2.5.3', |
|
187
|
|
|
'2.6' => '2.6.4', |
|
188
|
|
|
'2.7' => '2.7.3', |
|
189
|
|
|
'2.8' => '2.8.3', |
|
190
|
|
|
'2.9' => '2.9.4', |
|
191
|
|
|
'3.0' => '3.0.4', |
|
192
|
|
|
'3.1' => '3.1.3', |
|
193
|
|
|
'3.2' => '3.2.3', |
|
194
|
|
|
'3.3' => '3.3.4', |
|
195
|
|
|
'3.4' => '3.4.4', |
|
196
|
|
|
'3.5' => '3.5.4', |
|
197
|
|
|
'3.6' => '3.6.2', |
|
198
|
|
|
'3.7' => '3.7.3', |
|
199
|
|
|
'3.8' => '3.8.3', |
|
200
|
|
|
'3.9' => '3.9.7', |
|
201
|
|
|
'4.0' => '4.0.3', |
|
202
|
|
|
); |
|
203
|
|
|
|
|
204
|
|
|
$parts = explode( '.', JETPACK__VERSION, 3 ); |
|
205
|
|
|
if ( count( $parts ) < 2 ) { |
|
206
|
|
|
// no/not enough periods in the version; |
|
207
|
|
|
return false; |
|
208
|
|
|
} |
|
209
|
|
|
|
|
210
|
|
|
// pull out the first two components, cast to int to get rid of weird 'beta2' junk |
|
211
|
|
|
$int_parts = array(); |
|
212
|
|
|
$int_parts[0] = intval( $parts[0] ); |
|
213
|
|
|
$int_parts[1] = intval( $parts[1] ); |
|
214
|
|
|
|
|
215
|
|
|
// and find the secure version for this branch |
|
216
|
|
|
$branch = sprintf( '%d.%d', $int_parts[0], $int_parts[1] ); |
|
217
|
|
|
if ( ! isset( $secure_jetpacks[ $branch ] ) ) { |
|
218
|
|
|
return false; |
|
219
|
|
|
} |
|
220
|
|
|
return version_compare( JETPACK__VERSION, $secure_jetpacks[ $branch ], '<' ); |
|
221
|
|
|
} |
|
222
|
|
|
|
|
223
|
|
|
function disable_jetpack_oembed( $enabled ) { |
|
224
|
|
|
return false; |
|
225
|
|
|
} |
|
226
|
|
|
|
|
227
|
|
|
function filter_long_comment_xss( $commentdata ) { |
|
228
|
|
|
if ( strlen( $commentdata['comment_content'] ) > 65500 ) |
|
229
|
|
|
wp_die( 'Comment too long', 'Invalid comment' ); |
|
230
|
|
|
|
|
231
|
|
|
return $commentdata; |
|
232
|
|
|
} |
|
233
|
|
|
|
|
234
|
|
|
function wp_check_filetype_and_ext( $filetype, $file, $filename, $mimes ) { |
|
235
|
|
|
if ( empty( $mimes ) ) |
|
236
|
|
|
$mimes = get_allowed_mime_types(); |
|
237
|
|
|
$type = false; |
|
238
|
|
|
$ext = false; |
|
239
|
|
|
foreach ( $mimes as $ext_preg => $mime_match ) { |
|
240
|
|
|
$ext_preg = '!\.(' . $ext_preg . ')$!i'; |
|
241
|
|
|
if ( preg_match( $ext_preg, $filename, $ext_matches ) ) { |
|
242
|
|
|
$type = $mime_match; |
|
243
|
|
|
$ext = $ext_matches[1]; |
|
244
|
|
|
break; |
|
245
|
|
|
} |
|
246
|
|
|
} |
|
247
|
|
|
$filetype['ext'] = $ext; |
|
248
|
|
|
$filetype['type'] = $type; |
|
249
|
|
|
return $filetype; |
|
250
|
|
|
} |
|
251
|
|
|
|
|
252
|
|
|
function disable_jetpack_xmlrpc_methods_293( $jetpack_methods, $core_methods, $user = false ) { |
|
253
|
|
|
if ( $this->needs_jetpack_293_fix() && !$user ) |
|
254
|
|
|
unset( $jetpack_methods['jetpack.jsonAPI'], $jetpack_methods['jetpack.verifyAction'] ); |
|
255
|
|
|
return $jetpack_methods; |
|
256
|
|
|
} |
|
257
|
|
|
|
|
258
|
|
|
function disable_xmlrpc_methods_293( $core_methods ) { |
|
259
|
|
|
if ( $this->needs_jetpack_293_fix() ) |
|
260
|
|
|
unset( $core_methods['jetpack.verifyAction'] ); |
|
261
|
|
|
return $core_methods; |
|
262
|
|
|
} |
|
263
|
|
|
|
|
264
|
|
|
function needs_jetpack_293_fix() { |
|
265
|
|
|
if ( ! defined( 'JETPACK__VERSION' ) ) |
|
266
|
|
|
return false; |
|
267
|
|
|
$secure_jetpacks = array( |
|
268
|
|
|
'1.9' => '1.9.3', |
|
269
|
|
|
'2.0' => '2.0.5', |
|
270
|
|
|
'2.1' => '2.1.3', |
|
271
|
|
|
'2.2' => '2.2.6', |
|
272
|
|
|
'2.3' => '2.3.6', |
|
273
|
|
|
'2.4' => '2.4.3', |
|
274
|
|
|
'2.5' => '2.5.1', |
|
275
|
|
|
'2.6' => '2.6.2', |
|
276
|
|
|
'2.7' => '2.7.1', |
|
277
|
|
|
'2.8' => '2.8.1', |
|
278
|
|
|
'2.9' => '2.9.3', |
|
279
|
|
|
); |
|
280
|
|
|
$float_version = (string) floatval( JETPACK__VERSION ); |
|
281
|
|
|
if ( ! isset( $secure_jetpacks[ $float_version ] ) ) |
|
282
|
|
|
return false; |
|
283
|
|
|
return version_compare( JETPACK__VERSION, $secure_jetpacks[ $float_version ], '<' ); |
|
284
|
|
|
} |
|
285
|
|
|
|
|
286
|
|
|
function r21138_xmlrpc_edit_posts( $caps, $cap, $user_id, $args ) { |
|
287
|
|
|
if ( ! isset( $args[0] ) || isset( $args[1] ) && $args[1] === 'hotfixed' ) |
|
288
|
|
|
return $caps; |
|
289
|
|
|
foreach ( get_post_types( array(), 'objects' ) as $post_type_object ) { |
|
290
|
|
|
if ( $cap === $post_type_object->cap->edit_posts ) |
|
291
|
|
|
return map_meta_cap( $post_type_object->cap->edit_post, $user_id, $args[0], 'hotfixed' ); |
|
292
|
|
|
} |
|
293
|
|
|
return $caps; |
|
294
|
|
|
} |
|
295
|
|
|
|
|
296
|
|
|
function r21152_unfiltered_html( $caps, $cap, $user_id, $args ) { |
|
297
|
|
|
if ( $cap !== 'unfiltered_html' ) |
|
298
|
|
|
return $caps; |
|
299
|
|
|
if ( defined( 'DISALLOW_UNFILTERED_HTML' ) && DISALLOW_UNFILTERED_HTML ) |
|
300
|
|
|
return $caps; |
|
301
|
|
|
$key = array_search( 'do_not_allow', $caps ); |
|
302
|
|
|
if ( false !== $key ) |
|
303
|
|
|
return $caps; |
|
304
|
|
|
if ( is_multisite() && ! is_super_admin( $user_id ) ) |
|
305
|
|
|
$caps[$key] = 'do_not_allow'; |
|
306
|
|
|
return $caps; |
|
307
|
|
|
} |
|
308
|
|
|
|
|
309
|
|
|
function get_pagenum_link( $url ) { |
|
310
|
|
|
return esc_url_raw( $url ); |
|
311
|
|
|
} |
|
312
|
|
|
|
|
313
|
|
|
function r20486_comment_post_redirect( $location ) { |
|
314
|
|
|
$location = wp_sanitize_redirect( $location ); |
|
315
|
|
|
$location = wp_validate_redirect( $location, admin_url() ); |
|
316
|
|
|
|
|
317
|
|
|
return $location; |
|
318
|
|
|
} |
|
319
|
|
|
|
|
320
|
|
|
function r20493_make_clickable( $text ) { |
|
321
|
|
|
$r = ''; |
|
322
|
|
|
$textarr = preg_split( '/(<[^<>]+>)/', $text, -1, PREG_SPLIT_DELIM_CAPTURE ); // split out HTML tags |
|
323
|
|
|
foreach ( $textarr as $piece ) { |
|
324
|
|
|
if ( empty( $piece ) || ( $piece[0] == '<' && ! preg_match('|^<\s*[\w]{1,20}+://|', $piece) ) ) { |
|
325
|
|
|
$r .= $piece; |
|
326
|
|
|
continue; |
|
327
|
|
|
} |
|
328
|
|
|
|
|
329
|
|
|
// Long strings might contain expensive edge cases ... |
|
330
|
|
|
if ( 10000 < strlen( $piece ) ) { |
|
331
|
|
|
// ... break it up |
|
332
|
|
|
foreach ( $this->r20493_split_str_by_whitespace( $piece, 2100 ) as $chunk ) { // 2100: Extra room for scheme and leading and trailing paretheses |
|
333
|
|
|
if ( 2101 < strlen( $chunk ) ) { |
|
334
|
|
|
$r .= $chunk; // Too big, no whitespace: bail. |
|
335
|
|
|
} else { |
|
336
|
|
|
$r .= $this->r20493_make_clickable( $chunk ); |
|
337
|
|
|
} |
|
338
|
|
|
} |
|
339
|
|
|
} else { |
|
340
|
|
|
$ret = " $piece "; // Pad with whitespace to simplify the regexes |
|
341
|
|
|
|
|
342
|
|
|
$url_clickable = '~ |
|
343
|
|
|
([\\s(<.,;:!?]) # 1: Leading whitespace, or punctuation |
|
344
|
|
|
( # 2: URL |
|
345
|
|
|
[\\w]{1,20}+:// # Scheme and hier-part prefix |
|
346
|
|
|
(?=\S{1,2000}\s) # Limit to URLs less than about 2000 characters long |
|
347
|
|
|
[\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]*+ # Non-punctuation URL character |
|
348
|
|
|
(?: # Unroll the Loop: Only allow puctuation URL character if followed by a non-punctuation URL character |
|
349
|
|
|
[\'.,;:!?)] # Punctuation URL character |
|
350
|
|
|
[\\w\\x80-\\xff#%\\~/@\\[\\]*(+=&$-]++ # Non-punctuation URL character |
|
351
|
|
|
)* |
|
352
|
|
|
) |
|
353
|
|
|
(\)?) # 3: Trailing closing parenthesis (for parethesis balancing post processing) |
|
354
|
|
|
~xS'; // The regex is a non-anchored pattern and does not have a single fixed starting character. |
|
355
|
|
|
// Tell PCRE to spend more time optimizing since, when used on a page load, it will probably be used several times. |
|
356
|
|
|
|
|
357
|
|
|
$ret = preg_replace_callback( $url_clickable, array( $this, 'r20493_make_url_clickable_cb') , $ret ); |
|
358
|
|
|
|
|
359
|
|
|
$ret = preg_replace_callback( '#([\s>])((www|ftp)\.[\w\\x80-\\xff\#$%&~/.\-;:=,?@\[\]+]+)#is', '_make_web_ftp_clickable_cb', $ret ); |
|
360
|
|
|
$ret = preg_replace_callback( '#([\s>])([.0-9a-z_+-]+)@(([0-9a-z-]+\.)+[0-9a-z]{2,})#i', '_make_email_clickable_cb', $ret ); |
|
361
|
|
|
|
|
362
|
|
|
$ret = substr( $ret, 1, -1 ); // Remove our whitespace padding. |
|
363
|
|
|
$r .= $ret; |
|
364
|
|
|
} |
|
365
|
|
|
} |
|
366
|
|
|
|
|
367
|
|
|
// Cleanup of accidental links within links |
|
368
|
|
|
$r = preg_replace( '#(<a( [^>]+?>|>))<a [^>]+?>([^>]+?)</a></a>#i', "$1$3</a>", $r ); |
|
369
|
|
|
return $r; |
|
370
|
|
|
} |
|
371
|
|
|
|
|
372
|
|
|
function r20493_make_url_clickable_cb($matches) { |
|
373
|
|
|
$url = $matches[2]; |
|
374
|
|
|
|
|
375
|
|
|
if ( ')' == $matches[3] && strpos( $url, '(' ) ) { |
|
376
|
|
|
// If the trailing character is a closing parethesis, and the URL has an opening parenthesis in it, add the closing parenthesis to the URL. |
|
377
|
|
|
// Then we can let the parenthesis balancer do its thing below. |
|
378
|
|
|
$url .= $matches[3]; |
|
379
|
|
|
$suffix = ''; |
|
380
|
|
|
} else { |
|
381
|
|
|
$suffix = $matches[3]; |
|
382
|
|
|
} |
|
383
|
|
|
|
|
384
|
|
|
// Include parentheses in the URL only if paired |
|
385
|
|
|
while ( substr_count( $url, '(' ) < substr_count( $url, ')' ) ) { |
|
386
|
|
|
$suffix = strrchr( $url, ')' ) . $suffix; |
|
387
|
|
|
$url = substr( $url, 0, strrpos( $url, ')' ) ); |
|
388
|
|
|
} |
|
389
|
|
|
|
|
390
|
|
|
$url = esc_url($url); |
|
391
|
|
|
if ( empty($url) ) |
|
392
|
|
|
return $matches[0]; |
|
393
|
|
|
|
|
394
|
|
|
return $matches[1] . "<a href=\"$url\" rel=\"nofollow\">$url</a>" . $suffix; |
|
395
|
|
|
} |
|
396
|
|
|
|
|
397
|
|
|
function r20493_split_str_by_whitespace( $string, $goal ) { |
|
398
|
|
|
$chunks = array(); |
|
399
|
|
|
|
|
400
|
|
|
$string_nullspace = strtr( $string, "\r\n\t\v\f ", "\000\000\000\000\000\000" ); |
|
401
|
|
|
|
|
402
|
|
|
while ( $goal < strlen( $string_nullspace ) ) { |
|
403
|
|
|
$pos = strrpos( substr( $string_nullspace, 0, $goal + 1 ), "\000" ); |
|
404
|
|
|
|
|
405
|
|
|
if ( false === $pos ) { |
|
406
|
|
|
$pos = strpos( $string_nullspace, "\000", $goal + 1 ); |
|
407
|
|
|
if ( false === $pos ) { |
|
408
|
|
|
break; |
|
409
|
|
|
} |
|
410
|
|
|
} |
|
411
|
|
|
|
|
412
|
|
|
$chunks[] = substr( $string, 0, $pos + 1 ); |
|
413
|
|
|
$string = substr( $string, $pos + 1 ); |
|
414
|
|
|
$string_nullspace = substr( $string_nullspace, $pos + 1 ); |
|
415
|
|
|
} |
|
416
|
|
|
|
|
417
|
|
|
if ( $string ) { |
|
418
|
|
|
$chunks[] = $string; |
|
419
|
|
|
} |
|
420
|
|
|
|
|
421
|
|
|
return $chunks; |
|
422
|
|
|
} |
|
423
|
|
|
|
|
424
|
|
|
function r16625( $query ) { |
|
425
|
|
|
// Hotfixes: http://core.trac.wordpress.org/changeset/16625 |
|
426
|
|
|
|
|
427
|
|
|
// Punt as fast as possible if this isn't an UPDATE |
|
428
|
|
|
if ( substr( $query, 0, 6 ) != "UPDATE" ) |
|
429
|
|
|
return $query; |
|
430
|
|
|
global $wpdb; |
|
431
|
|
|
|
|
432
|
|
|
// Determine what the prefix of the bad query would look like and punt if this query doesn't match |
|
433
|
|
|
$badstring = "UPDATE $wpdb->posts SET to_ping = TRIM(REPLACE(to_ping, '"; |
|
434
|
|
|
if ( substr( $query, 0, strlen( $badstring ) ) != $badstring ) |
|
435
|
|
|
return $query; |
|
436
|
|
|
|
|
437
|
|
|
// Pull the post_id which is the last thing in the origin query, after a space, no quotes |
|
438
|
|
|
$query_parts = explode( " ", $query ); |
|
439
|
|
|
$post_id = array_pop( $query_parts ); |
|
440
|
|
|
|
|
441
|
|
|
// Chop off the beginning and end of the original query to get our unsanitized $tb_ping |
|
442
|
|
|
$tb_ping = substr( |
|
443
|
|
|
$query, |
|
444
|
|
|
strlen( $badstring ), |
|
445
|
|
|
( |
|
446
|
|
|
strlen( $query ) - ( |
|
447
|
|
|
strlen( $badstring ) + strlen( sprintf( "', '')) WHERE ID = %d", $post_id ) ) |
|
448
|
|
|
) |
|
449
|
|
|
) |
|
450
|
|
|
); |
|
451
|
|
|
|
|
452
|
|
|
// Return the fixed query |
|
453
|
|
|
return $wpdb->prepare( "UPDATE $wpdb->posts SET to_ping = TRIM(REPLACE(to_ping, %s, '')) WHERE ID = %d", $tb_ping, $post_id ); |
|
454
|
|
|
} |
|
455
|
|
|
|
|
456
|
|
|
function filter_xmlrpc_methods( $xmlrpc_method ) { |
|
457
|
|
|
// Hotfixes: http://core.trac.wordpress.org/changeset/16803 |
|
458
|
|
|
global $wp_xmlrpc_server; |
|
459
|
|
|
// Pretend that we are an xmlrpc method, freshly called |
|
460
|
|
|
$args = $wp_xmlrpc_server->message->params; |
|
461
|
|
|
$error_code = 401; |
|
462
|
|
|
switch( $xmlrpc_method ) { |
|
463
|
|
|
case 'metaWeblog.newPost': |
|
464
|
|
|
$content_struct = $args[3]; |
|
465
|
|
|
$publish = isset( $args[4] ) ? $args[4] : 0; |
|
466
|
|
|
if ( !empty( $content_struct['post_type'] ) ) { |
|
467
|
|
|
if ( $content_struct['post_type'] == 'page' ) { |
|
468
|
|
|
if ( $publish || 'publish' == $content_struct['page_status'] ) |
|
469
|
|
|
$cap = 'publish_pages'; |
|
470
|
|
|
else |
|
471
|
|
|
$cap = 'edit_pages'; |
|
472
|
|
|
$error_message = __( 'Sorry, you are not allowed to publish pages on this site.' ); |
|
473
|
|
View Code Duplication |
} elseif ( $content_struct['post_type'] == 'post' ) { |
|
474
|
|
|
if ( $publish || 'publish' == $content_struct['post_status'] ) |
|
475
|
|
|
$cap = 'publish_posts'; |
|
476
|
|
|
else |
|
477
|
|
|
$cap = 'edit_posts'; |
|
478
|
|
|
$error_message = __( 'Sorry, you are not allowed to publish posts on this site.' ); |
|
479
|
|
|
} else { |
|
480
|
|
|
$error_message = __( 'Invalid post type.' ); |
|
481
|
|
|
} |
|
482
|
|
View Code Duplication |
} else { |
|
483
|
|
|
if ( $publish || 'publish' == $content_struct['post_status'] ) |
|
484
|
|
|
$cap = 'publish_posts'; |
|
485
|
|
|
else |
|
486
|
|
|
$cap = 'edit_posts'; |
|
487
|
|
|
$error_message = __( 'Sorry, you are not allowed to publish posts on this site.' ); |
|
488
|
|
|
} |
|
489
|
|
|
if ( current_user_can( $cap ) ) |
|
|
|
|
|
|
490
|
|
|
return true; |
|
491
|
|
|
break; |
|
492
|
|
|
case 'metaWeblog.editPost': |
|
493
|
|
|
$post_ID = (int) $args[0]; |
|
|
|
|
|
|
494
|
|
|
$content_struct = $args[3]; |
|
495
|
|
|
$publish = $args[4] || ( isset( $content_struct['post_status'] ) && in_array( $content_struct['post_status'], array( 'publish', 'private' ) ) ); |
|
496
|
|
|
$cap = ( $publish ) ? 'publish_posts' : 'edit_posts'; |
|
497
|
|
|
$error_message = __( 'Sorry, you are not allowed to publish posts on this site.' ); |
|
498
|
|
|
if ( !empty( $content_struct['post_type'] ) ) { |
|
499
|
|
|
if ( $content_struct['post_type'] == 'page' ) { |
|
500
|
|
|
$error_message = __( 'Sorry, you are not allowed to publish pages on this site.' ); |
|
501
|
|
|
} elseif ( $content_struct['post_type'] == 'post' ) { |
|
502
|
|
|
$error_message = __( 'Sorry, you are not allowed to publish posts on this site.' ); |
|
503
|
|
|
} else { |
|
504
|
|
|
$error_message = __( 'Invalid post type.' ); |
|
505
|
|
|
} |
|
506
|
|
|
} |
|
507
|
|
|
if ( current_user_can( $cap ) ) |
|
508
|
|
|
return true; |
|
509
|
|
|
break; |
|
510
|
|
|
case 'mt.publishPost': |
|
511
|
|
|
$post_ID = (int) $args[0]; |
|
512
|
|
|
if ( current_user_can( 'publish_posts' ) && current_user_can( 'edit_post', $post_ID ) ) |
|
513
|
|
|
return true; |
|
514
|
|
|
$error_message = __( 'Sorry, you cannot edit this post.' ); |
|
515
|
|
|
break; |
|
516
|
|
|
case 'blogger.deletePost': |
|
517
|
|
|
$post_ID = (int) $args[1]; |
|
518
|
|
|
if ( current_user_can( 'delete_post', $post_ID ) ) |
|
519
|
|
|
return true; |
|
520
|
|
|
$error_message = __( 'Sorry, you do not have the right to delete this post.' ); |
|
521
|
|
|
break; |
|
522
|
|
|
case 'wp.getPageStatusList': |
|
523
|
|
|
if ( current_user_can( 'edit_pages' ) ) |
|
524
|
|
|
return true; |
|
525
|
|
|
$error_code = 403; |
|
526
|
|
|
$error_message = __( 'You are not allowed access to details about this site.' ); |
|
527
|
|
|
break; |
|
528
|
|
|
case 'wp.deleteComment': |
|
529
|
|
|
case 'wp.editComment': |
|
530
|
|
|
$comment_ID = (int) $args[3]; |
|
531
|
|
|
if ( !$comment = get_comment( $comment_ID ) ) |
|
532
|
|
|
return true; // This will be handled in the calling function explicitly |
|
533
|
|
|
if ( current_user_can( 'edit_post', $comment->comment_post_ID ) ) |
|
534
|
|
|
return true; |
|
535
|
|
|
$error_code = 403; |
|
536
|
|
|
$error_message = __( 'You are not allowed to moderate comments on this site.' ); |
|
537
|
|
|
break; |
|
538
|
|
|
default: |
|
539
|
|
|
return true; |
|
540
|
|
|
} |
|
541
|
|
|
// If we are here then this was a handlable xmlrpc call and the capability checks above all failed |
|
542
|
|
|
// ( otherwise they would have returned to the do_action from the switch statement above ) so it's |
|
543
|
|
|
// time to exit with whatever error we've determined is the problem (thus short circuiting the |
|
544
|
|
|
// original XMLRPC method call, and enforcing the above capability checks -- with an ax. We'll |
|
545
|
|
|
// mimic the behavior from the end of IXR_Server::serve() |
|
546
|
|
|
$r = new IXR_Error( $error_code, $error_message ); |
|
547
|
|
|
$resultxml = $r->getXml(); |
|
548
|
|
|
$xml = <<<EOD |
|
549
|
|
|
<methodResponse> |
|
550
|
|
|
<params> |
|
551
|
|
|
<param> |
|
552
|
|
|
<value> |
|
553
|
|
|
$resultxml |
|
554
|
|
|
</value> |
|
555
|
|
|
</param> |
|
556
|
|
|
</params> |
|
557
|
|
|
</methodResponse> |
|
558
|
|
|
EOD; |
|
559
|
|
|
$wp_xmlrpc_server->output( $xml ); |
|
560
|
|
|
// For good measure... |
|
561
|
|
|
die(); |
|
562
|
|
|
} |
|
563
|
|
|
|
|
564
|
|
|
function r17172_esc_url( $url, $original_url, $_context ) { |
|
565
|
|
|
$url = $original_url; |
|
566
|
|
|
|
|
567
|
|
|
if ( '' == $url ) |
|
568
|
|
|
return $url; |
|
569
|
|
|
$url = preg_replace('|[^a-z0-9-~+_.?#=!&;,/:%@$\|*\'()\\x80-\\xff]|i', '', $url); |
|
570
|
|
|
$strip = array('%0d', '%0a', '%0D', '%0A'); |
|
571
|
|
|
$url = _deep_replace($strip, $url); |
|
572
|
|
|
$url = str_replace(';//', '://', $url); |
|
573
|
|
|
/* If the URL doesn't appear to contain a scheme, we |
|
574
|
|
|
* presume it needs http:// appended (unless a relative |
|
575
|
|
|
* link starting with /, # or ? or a php file). |
|
576
|
|
|
*/ |
|
577
|
|
|
if ( strpos($url, ':') === false && ! in_array( $url[0], array( '/', '#', '?' ) ) && |
|
578
|
|
|
! preg_match('/^[a-z0-9-]+?\.php/i', $url) ) |
|
579
|
|
|
$url = 'http://' . $url; |
|
580
|
|
|
|
|
581
|
|
|
// Replace ampersands and single quotes only when displaying. |
|
582
|
|
|
if ( 'display' == $_context ) { |
|
583
|
|
|
$url = wp_kses_normalize_entities( $url ); |
|
584
|
|
|
$url = str_replace( '&', '&', $url ); |
|
585
|
|
|
$url = str_replace( "'", ''', $url ); |
|
586
|
|
|
} |
|
587
|
|
|
|
|
588
|
|
|
$protocols = array ('http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet', 'mms', 'rtsp', 'svn'); |
|
589
|
|
|
if ( VaultPress_kses::wp_kses_bad_protocol( $url, $protocols ) != $url ) |
|
590
|
|
|
return ''; |
|
591
|
|
|
return $url; |
|
592
|
|
|
} |
|
593
|
|
|
|
|
594
|
|
|
// http://core.trac.wordpress.org/changeset/17172 |
|
595
|
|
|
// http://core.trac.wordpress.org/changeset/20541 |
|
596
|
|
|
function r17172_wp_kses( $string, $html, $protocols ) { |
|
597
|
|
|
return VaultPress_kses::wp_kses( $string, $html, $protocols ); |
|
598
|
|
|
} |
|
599
|
|
|
|
|
600
|
|
|
// http://core.trac.wordpress.org/changeset/17990 |
|
601
|
|
|
function r17990( $filename ) { |
|
602
|
|
|
$parts = explode('.', $filename); |
|
603
|
|
|
$filename = array_shift($parts); |
|
604
|
|
|
$extension = array_pop($parts); |
|
605
|
|
|
$mimes = get_allowed_mime_types(); |
|
606
|
|
|
|
|
607
|
|
|
// Loop over any intermediate extensions. Munge them with a trailing underscore if they are a 2 - 5 character |
|
608
|
|
|
// long alpha string not in the extension whitelist. |
|
609
|
|
|
foreach ( (array) $parts as $part) { |
|
610
|
|
|
$filename .= '.' . $part; |
|
611
|
|
|
|
|
612
|
|
|
if ( preg_match("/^[a-zA-Z]{2,5}\d?$/", $part) ) { |
|
613
|
|
|
$allowed = false; |
|
614
|
|
|
foreach ( $mimes as $ext_preg => $mime_match ) { |
|
615
|
|
|
$ext_preg = '!^(' . $ext_preg . ')$!i'; |
|
616
|
|
|
if ( preg_match( $ext_preg, $part ) ) { |
|
617
|
|
|
$allowed = true; |
|
618
|
|
|
break; |
|
619
|
|
|
} |
|
620
|
|
|
} |
|
621
|
|
|
if ( !$allowed ) |
|
622
|
|
|
$filename .= '_'; |
|
623
|
|
|
} |
|
624
|
|
|
} |
|
625
|
|
|
$filename .= '.' . $extension; |
|
626
|
|
|
return $filename; |
|
627
|
|
|
} |
|
628
|
|
|
|
|
629
|
|
|
/* |
|
630
|
|
|
* Hotfixes: http://core.trac.wordpress.org/changeset/18368 |
|
631
|
|
|
*/ |
|
632
|
|
|
function r18368( $post, $raw_post ) { |
|
633
|
|
|
if ( isset( $post['filter'] ) || isset ( $raw_post['filter'] ) ) { |
|
634
|
|
|
unset( $post['filter'], $raw_post['filter'] ); // to ensure the post is properly sanitized |
|
635
|
|
|
$post = sanitize_post($post, 'db'); |
|
636
|
|
|
} |
|
637
|
|
|
if ( empty( $post['ID'] ) ) |
|
638
|
|
|
unset( $post['ID'] ); // sanitize_post |
|
639
|
|
|
unset( $post['filter'] ); // sanitize_post |
|
640
|
|
|
return $post; |
|
641
|
|
|
} |
|
642
|
|
|
|
|
643
|
|
|
/** |
|
644
|
|
|
* Protect WordPress internal metadata. |
|
645
|
|
|
* |
|
646
|
|
|
* The post data is passed as a parameter to (unit) test this method. |
|
647
|
|
|
* @param $post_data|array the $_POST array. |
|
648
|
|
|
*/ |
|
649
|
|
|
function r17994( &$post_data ) { |
|
650
|
|
|
// Protect admin-ajax add_meta |
|
651
|
|
|
$metakeyselect = isset( $post_data['metakeyselect'] ) ? stripslashes( trim( $post_data['metakeyselect'] ) ) : ''; |
|
652
|
|
|
$metakeyinput = isset( $post_data['metakeyinput'] ) ? stripslashes( trim( $post_data['metakeyinput'] ) ) : ''; |
|
653
|
|
|
|
|
654
|
|
|
if ( ( $metakeyselect && '_' == $metakeyselect[0] ) || ( $metakeyinput && '_' == $metakeyinput[0] ) ) { |
|
655
|
|
|
unset( $_POST['metakeyselect'], $_POST['metakeyinput'] ); |
|
656
|
|
|
} |
|
657
|
|
|
|
|
658
|
|
|
// Protect admin-ajax update_meta |
|
659
|
|
|
if ( isset( $post_data['meta'] ) ) { |
|
660
|
|
|
foreach ( (array)$post_data['meta'] as $mid => $value ) { |
|
661
|
|
|
$key = stripslashes( $post_data['meta'][$mid]['key'] ); |
|
662
|
|
|
if ( $key && '_' == $key[0] ) |
|
663
|
|
|
unset( $post_data['meta'][$mid] ); |
|
664
|
|
|
} |
|
665
|
|
|
} |
|
666
|
|
|
} |
|
667
|
|
|
|
|
668
|
|
|
function r17994_sanitize_mime_type( $mime_type ) { |
|
669
|
|
|
$sani_mime_type = preg_replace( '/[^\-*.a-zA-Z0-9\/+]/', '', $mime_type ); |
|
670
|
|
|
return apply_filters( 'sanitize_mime_type', $sani_mime_type, $mime_type ); |
|
|
|
|
|
|
671
|
|
|
} |
|
672
|
|
|
|
|
673
|
|
|
function r17826_send_frame_options_header() { |
|
674
|
|
|
@header( 'X-Frame-Options: SAMEORIGIN' ); |
|
|
|
|
|
|
675
|
|
|
} |
|
676
|
|
|
|
|
677
|
|
|
function r18346_sanitize_admin_email_on_save($value) { |
|
678
|
|
|
$value = sanitize_email( $value ); |
|
679
|
|
|
if ( !is_email( $value ) ) { |
|
680
|
|
|
$value = get_option( 'new_admin_email' ); // Resets option to stored value in the case of failed sanitization |
|
681
|
|
|
if ( function_exists( 'add_settings_error' ) ) |
|
682
|
|
|
add_settings_error( 'new_admin_email', 'invalid_admin_email', __( 'The email address entered did not appear to be a valid email address. Please enter a valid email address.' ) ); |
|
683
|
|
|
} |
|
684
|
|
|
return $value; |
|
685
|
|
|
} |
|
686
|
|
|
|
|
687
|
|
|
function r18346_sanitize_admin_email( $value ) { |
|
688
|
|
|
return sanitize_email( $value ); // Is it enough ? |
|
689
|
|
|
} |
|
690
|
|
|
|
|
691
|
|
|
function r18346_sanitize_lang_on_save( $value ) { |
|
692
|
|
|
$value = $this->r18346_sanitize_lang( $value ); // sanitize the new value. |
|
693
|
|
|
if ( empty( $value ) ) |
|
694
|
|
|
$value = get_option( 'WPLANG' ); |
|
695
|
|
|
return $value; |
|
696
|
|
|
} |
|
697
|
|
|
|
|
698
|
|
|
function r18346_sanitize_lang( $value ) { |
|
699
|
|
|
$allowed = apply_filters( 'available_languages', get_available_languages() ); // add a filter to unit test |
|
700
|
|
|
if ( !empty( $value ) && !in_array( $value, $allowed ) ) |
|
701
|
|
|
return false; |
|
702
|
|
|
else |
|
703
|
|
|
return $value; |
|
704
|
|
|
} |
|
705
|
|
|
|
|
706
|
|
|
// Protect All-in-one SEO AJAX calls from script injection and changes without privileges. Affects versions <= 2.1.5 |
|
707
|
|
|
function protect_aioseo_ajax() { |
|
708
|
|
|
if ( defined( 'AIOSEOP_VERSION' ) && version_compare( AIOSEOP_VERSION, '2.1.5', '>' ) ) |
|
709
|
|
|
return; |
|
710
|
|
|
|
|
711
|
|
|
if ( ! isset( $_POST['post_id'] ) || ! isset( $_POST['target_meta'] ) ) |
|
712
|
|
|
die(); |
|
713
|
|
|
|
|
714
|
|
|
// Ensure the current user has permission to write to the post. |
|
715
|
|
|
if ( ! current_user_can( 'edit_post', intval( $_POST['post_id'] ) ) ) |
|
716
|
|
|
die(); |
|
717
|
|
|
|
|
718
|
|
|
// Limit the fields that can be written to |
|
719
|
|
|
if ( ! in_array( $_POST['target_meta'], array( 'title', 'description', 'keywords' ) ) ) |
|
720
|
|
|
die(); |
|
721
|
|
|
|
|
722
|
|
|
// Strip tags from the metadata value. |
|
723
|
|
|
$_POST['new_meta'] = strip_tags( $_POST['new_meta'] ); |
|
724
|
|
|
} |
|
725
|
|
|
|
|
726
|
|
|
// Protect The MailPoet plugin (wysija-newsletters) from remote file upload. Affects versions <= 2.6.6 |
|
727
|
|
|
function protect_wysija_newsletters_verify_capability() { |
|
728
|
|
|
if ( !class_exists( 'WYSIJA_object' ) ) |
|
729
|
|
|
return true; |
|
730
|
|
|
if ( version_compare( WYSIJA::get_version(), '2.6.7', '>=' ) ) |
|
731
|
|
|
return true; |
|
732
|
|
|
if ( !defined( 'DOING_AJAX' ) && !defined( 'WYSIJA_ITF' ) ) |
|
733
|
|
|
return true; |
|
734
|
|
|
if( isset( $_REQUEST['page'] ) && substr( $_REQUEST['page'] ,0 ,7 ) == 'wysija_' ){ |
|
735
|
|
|
|
|
736
|
|
|
switch( $_REQUEST['page'] ){ |
|
737
|
|
|
case 'wysija_campaigns': |
|
738
|
|
|
$role_needed = 'wysija_newsletters'; |
|
739
|
|
|
break; |
|
740
|
|
|
case 'wysija_subscribers': |
|
741
|
|
|
$role_needed = 'wysija_subscribers'; |
|
742
|
|
|
break; |
|
743
|
|
|
case 'wysija_config': |
|
744
|
|
|
$role_needed = 'wysija_config'; |
|
745
|
|
|
break; |
|
746
|
|
|
case 'wysija_statistics': |
|
747
|
|
|
$role_needed = 'wysija_stats_dashboard'; |
|
748
|
|
|
break; |
|
749
|
|
|
default: |
|
750
|
|
|
$role_needed = 'switch_themes'; |
|
751
|
|
|
} |
|
752
|
|
|
|
|
753
|
|
|
if( current_user_can( $role_needed ) ){ |
|
754
|
|
|
return true; |
|
755
|
|
|
} else{ |
|
756
|
|
|
die( 'You are not allowed here.' ); |
|
757
|
|
|
} |
|
758
|
|
|
|
|
759
|
|
|
}else{ |
|
760
|
|
|
// this is not a wysija interface/action we can let it pass |
|
761
|
|
|
return true; |
|
762
|
|
|
} |
|
763
|
|
|
} |
|
764
|
|
|
|
|
765
|
|
|
// Protect the Revolution Slider plugin (revslider) from local file inclusion. Affects versions < 4.2 |
|
766
|
|
|
function protect_revslider_lfi() { |
|
767
|
|
|
if ( isset( $_GET['action'] ) && 'revslider_show_image' == $_GET['action'] ) { |
|
768
|
|
|
$img = ''; |
|
769
|
|
|
if ( isset( $_GET['img'] ) ) |
|
770
|
|
|
$img = $_GET['img']; |
|
771
|
|
|
if ( is_numeric( $img ) ) |
|
772
|
|
|
return; |
|
773
|
|
|
$validate = validate_file( $img ); |
|
774
|
|
|
if ( 0 !== $validate ) |
|
775
|
|
|
die( 'invalid file' ); |
|
776
|
|
|
if ( !file_exists( $img ) ) |
|
777
|
|
|
die( 'file does not exist' ); |
|
778
|
|
|
} |
|
779
|
|
|
} |
|
780
|
|
|
|
|
781
|
|
|
// Protect WooCommerce 2.0.20 - 2.3.10 from PayPal IPN object injection attack. |
|
782
|
|
|
function protect_woocommerce_paypal_object_injection() { |
|
783
|
|
|
global $woocommerce; |
|
784
|
|
|
if ( ! isset( $woocommerce ) ) |
|
785
|
|
|
return; |
|
786
|
|
|
|
|
787
|
|
|
$wc_version = $woocommerce->version; |
|
788
|
|
|
if ( version_compare( $wc_version, '2.0.20', '<' ) || version_compare( $wc_version, '2.3.11', '>=' ) ) |
|
789
|
|
|
return; |
|
790
|
|
|
|
|
791
|
|
|
if ( isset( $_REQUEST['paypalListener'] ) ) { |
|
792
|
|
|
$check_fields = array( 'custom', 'cm' ); |
|
793
|
|
|
foreach ( $check_fields as $field ) { |
|
794
|
|
|
if ( isset( $_REQUEST[ $field ] ) && preg_match( '/[CO]:\+?[0-9]+:/', $_REQUEST[ $field ] ) ) { |
|
795
|
|
|
die(); |
|
796
|
|
|
} |
|
797
|
|
|
} |
|
798
|
|
|
} |
|
799
|
|
|
} |
|
800
|
|
|
|
|
801
|
|
|
// Protect WordPress 3.1.0 -> WordPress 4.3.0 from code injection via user email |
|
802
|
|
|
function patch_user_email( $value, $user_id, $context ) { |
|
803
|
|
|
if ( 'display' === $context && class_exists( 'WP_Users_List_Table' ) ) { |
|
804
|
|
|
return esc_attr( $value ); |
|
805
|
|
|
} |
|
806
|
|
|
|
|
807
|
|
|
return $value; |
|
808
|
|
|
} |
|
809
|
|
|
|
|
810
|
|
|
// Protect WordPress < 4.3.1 from evil tags inside caption shortcodes |
|
811
|
|
|
function filtered_caption_shortcode( $attr, $content = null ) { |
|
812
|
|
|
if ( isset( $attr['caption'] ) && strpos( $attr['caption'], '<' ) !== false ) { |
|
813
|
|
|
$attr['caption'] = wp_kses( $attr['caption'], 'post' ); |
|
814
|
|
|
} |
|
815
|
|
|
|
|
816
|
|
|
return img_caption_shortcode( $attr, $content ); |
|
817
|
|
|
} |
|
818
|
|
|
|
|
819
|
|
|
// Protect Akismet < 3.1.5 from stored XSS in admin page |
|
820
|
|
|
function protect_akismet_comment_xss() { |
|
821
|
|
|
remove_filter( 'comment_text', array( 'Akismet_Admin', 'text_add_link_class' ) ); |
|
822
|
|
|
} |
|
823
|
|
|
} |
|
824
|
|
|
|
|
825
|
|
|
global $wp_version; |
|
826
|
|
|
$needs_class_fix = version_compare( $wp_version, '3.1', '>=') && version_compare( $wp_version, '3.1.3', '<' ); |
|
827
|
|
|
if ( defined( 'XMLRPC_REQUEST' ) && XMLRPC_REQUEST && $needs_class_fix ) { |
|
828
|
|
|
include_once( ABSPATH . WPINC . '/class-IXR.php' ); |
|
829
|
|
|
include_once( ABSPATH . WPINC . '/class-wp-xmlrpc-server.php' ); |
|
830
|
|
|
|
|
831
|
|
|
class VaultPress_XMLRPC_Server_r17994 extends wp_xmlrpc_server { |
|
832
|
|
|
function set_custom_fields( $post_id, $fields ) { |
|
833
|
|
|
foreach( $fields as $k => $meta ) { |
|
834
|
|
|
$key = stripslashes( trim( $meta['key'] ) ); |
|
835
|
|
|
if ( $key && '_' == $key[0] ) |
|
836
|
|
|
unset( $fields[$k] ); |
|
837
|
|
|
} |
|
838
|
|
|
parent::set_custom_fields( $post_id, $fields ); |
|
839
|
|
|
} |
|
840
|
|
|
} |
|
841
|
|
|
|
|
842
|
|
|
function r17994_xmlrpc_server() { |
|
843
|
|
|
return 'VaultPress_XMLRPC_Server_r17994'; |
|
844
|
|
|
} |
|
845
|
|
|
} |
|
846
|
|
|
|
|
847
|
|
|
class VaultPress_kses { |
|
848
|
|
|
static function wp_kses($string, $allowed_html, $allowed_protocols = array ()) { |
|
849
|
|
|
$string = wp_kses_no_null($string); |
|
850
|
|
|
$string = wp_kses_js_entities($string); |
|
851
|
|
|
$string = wp_kses_normalize_entities($string); |
|
852
|
|
|
return VaultPress_kses::wp_kses_split($string, $allowed_html, $allowed_protocols); |
|
853
|
|
|
} |
|
854
|
|
|
|
|
855
|
|
|
static function wp_kses_split($string, $allowed_html, $allowed_protocols) { |
|
856
|
|
|
global $pass_allowed_html, $pass_allowed_protocols; |
|
857
|
|
|
$pass_allowed_html = $allowed_html; |
|
858
|
|
|
$pass_allowed_protocols = $allowed_protocols; |
|
859
|
|
|
return preg_replace_callback( '%(<!--.*?(-->|$))|(<[^>]*(>|$)|>)%', 'VaultPress_kses::_vp_kses_split_callback', $string ); |
|
860
|
|
|
} |
|
861
|
|
|
|
|
862
|
|
|
static function _vp_kses_split_callback( $match ) { |
|
863
|
|
|
global $pass_allowed_html, $pass_allowed_protocols; |
|
864
|
|
|
return VaultPress_kses::wp_kses_split2( $match[0], $pass_allowed_html, $pass_allowed_protocols ); |
|
865
|
|
|
} |
|
866
|
|
|
|
|
867
|
|
|
static function wp_kses_split2($string, $allowed_html, $allowed_protocols) { |
|
868
|
|
|
$string = wp_kses_stripslashes($string); |
|
869
|
|
|
|
|
870
|
|
|
if (substr($string, 0, 1) != '<') |
|
871
|
|
|
return '>'; |
|
872
|
|
|
# It matched a ">" character |
|
873
|
|
|
|
|
874
|
|
|
if ( '<!--' == substr( $string, 0, 4 ) ) { |
|
875
|
|
|
$string = str_replace( array('<!--', '-->'), '', $string ); |
|
876
|
|
|
while ( $string != ($newstring = VaultPress_kses::wp_kses($string, $allowed_html, $allowed_protocols)) ) |
|
877
|
|
|
$string = $newstring; |
|
878
|
|
|
if ( $string == '' ) |
|
879
|
|
|
return ''; |
|
880
|
|
|
// prevent multiple dashes in comments |
|
881
|
|
|
$string = preg_replace('/--+/', '-', $string); |
|
882
|
|
|
// prevent three dashes closing a comment |
|
883
|
|
|
$string = preg_replace('/-$/', '', $string); |
|
884
|
|
|
return "<!--{$string}-->"; |
|
885
|
|
|
} |
|
886
|
|
|
# Allow HTML comments |
|
887
|
|
|
|
|
888
|
|
|
if (!preg_match('%^<\s*(/\s*)?([a-zA-Z0-9]+)([^>]*)>?$%', $string, $matches)) |
|
889
|
|
|
return ''; |
|
890
|
|
|
# It's seriously malformed |
|
891
|
|
|
|
|
892
|
|
|
$slash = trim($matches[1]); |
|
893
|
|
|
$elem = $matches[2]; |
|
894
|
|
|
$attrlist = $matches[3]; |
|
895
|
|
|
|
|
896
|
|
|
if ( ! isset($allowed_html[strtolower($elem)]) ) |
|
897
|
|
|
return ''; |
|
898
|
|
|
# They are using a not allowed HTML element |
|
899
|
|
|
|
|
900
|
|
|
if ($slash != '') |
|
901
|
|
|
return "</$elem>"; |
|
902
|
|
|
# No attributes are allowed for closing elements |
|
903
|
|
|
|
|
904
|
|
|
return VaultPress_kses::wp_kses_attr( $elem, $attrlist, $allowed_html, $allowed_protocols ); |
|
905
|
|
|
} |
|
906
|
|
|
|
|
907
|
|
|
static function wp_kses_attr($element, $attr, $allowed_html, $allowed_protocols) { |
|
908
|
|
|
# Is there a closing XHTML slash at the end of the attributes? |
|
909
|
|
|
|
|
910
|
|
|
$xhtml_slash = ''; |
|
911
|
|
|
if (preg_match('%\s*/\s*$%', $attr)) |
|
912
|
|
|
$xhtml_slash = ' /'; |
|
913
|
|
|
|
|
914
|
|
|
# Are any attributes allowed at all for this element? |
|
915
|
|
|
if ( ! isset($allowed_html[strtolower($element)]) || count($allowed_html[strtolower($element)]) == 0 ) |
|
916
|
|
|
return "<$element$xhtml_slash>"; |
|
917
|
|
|
|
|
918
|
|
|
# Split it |
|
919
|
|
|
$attrarr = VaultPress_kses::wp_kses_hair($attr, $allowed_protocols); |
|
920
|
|
|
|
|
921
|
|
|
# Go through $attrarr, and save the allowed attributes for this element |
|
922
|
|
|
# in $attr2 |
|
923
|
|
|
$attr2 = ''; |
|
924
|
|
|
|
|
925
|
|
|
$allowed_attr = $allowed_html[strtolower($element)]; |
|
926
|
|
|
foreach ($attrarr as $arreach) { |
|
927
|
|
|
if ( ! isset( $allowed_attr[strtolower($arreach['name'])] ) ) |
|
928
|
|
|
continue; # the attribute is not allowed |
|
929
|
|
|
|
|
930
|
|
|
$current = $allowed_attr[strtolower($arreach['name'])]; |
|
931
|
|
|
if ( $current == '' ) |
|
932
|
|
|
continue; # the attribute is not allowed |
|
933
|
|
|
|
|
934
|
|
|
if ( strtolower( $arreach['name'] ) == 'style' ) { |
|
935
|
|
|
$orig_value = $arreach['value']; |
|
936
|
|
|
$value = safecss_filter_attr( $orig_value ); |
|
937
|
|
|
|
|
938
|
|
|
if ( empty( $value ) ) |
|
939
|
|
|
continue; |
|
940
|
|
|
|
|
941
|
|
|
$arreach['value'] = $value; |
|
942
|
|
|
$arreach['whole'] = str_replace( $orig_value, $value, $arreach['whole'] ); |
|
943
|
|
|
} |
|
944
|
|
|
|
|
945
|
|
|
if ( ! is_array($current) ) { |
|
946
|
|
|
$attr2 .= ' '.$arreach['whole']; |
|
947
|
|
|
# there are no checks |
|
948
|
|
|
|
|
949
|
|
|
} else { |
|
950
|
|
|
# there are some checks |
|
951
|
|
|
$ok = true; |
|
952
|
|
|
foreach ($current as $currkey => $currval) { |
|
953
|
|
|
if ( ! wp_kses_check_attr_val($arreach['value'], $arreach['vless'], $currkey, $currval) ) { |
|
954
|
|
|
$ok = false; |
|
955
|
|
|
break; |
|
956
|
|
|
} |
|
957
|
|
|
} |
|
958
|
|
|
|
|
959
|
|
|
if ( $ok ) |
|
960
|
|
|
$attr2 .= ' '.$arreach['whole']; # it passed them |
|
961
|
|
|
} # if !is_array($current) |
|
962
|
|
|
} # foreach |
|
963
|
|
|
|
|
964
|
|
|
# Remove any "<" or ">" characters |
|
965
|
|
|
$attr2 = preg_replace('/[<>]/', '', $attr2); |
|
966
|
|
|
|
|
967
|
|
|
return "<$element$attr2$xhtml_slash>"; |
|
968
|
|
|
} |
|
969
|
|
|
|
|
970
|
|
|
static function wp_kses_hair($attr, $allowed_protocols) { |
|
971
|
|
|
$attrarr = array (); |
|
972
|
|
|
$mode = 0; |
|
973
|
|
|
$attrname = ''; |
|
974
|
|
|
$uris = array('xmlns', 'profile', 'href', 'src', 'cite', 'classid', 'codebase', 'data', 'usemap', 'longdesc', 'action'); |
|
975
|
|
|
|
|
976
|
|
|
# Loop through the whole attribute list |
|
977
|
|
|
|
|
978
|
|
|
while (strlen($attr) != 0) { |
|
979
|
|
|
$working = 0; # Was the last operation successful? |
|
980
|
|
|
|
|
981
|
|
|
switch ($mode) { |
|
982
|
|
|
case 0 : # attribute name, href for instance |
|
983
|
|
|
|
|
984
|
|
|
if (preg_match('/^([-a-zA-Z]+)/', $attr, $match)) { |
|
985
|
|
|
$attrname = $match[1]; |
|
986
|
|
|
$working = $mode = 1; |
|
987
|
|
|
$attr = preg_replace('/^[-a-zA-Z]+/', '', $attr); |
|
988
|
|
|
} |
|
989
|
|
|
|
|
990
|
|
|
break; |
|
991
|
|
|
|
|
992
|
|
|
case 1 : # equals sign or valueless ("selected") |
|
993
|
|
|
|
|
994
|
|
|
if (preg_match('/^\s*=\s*/', $attr)) # equals sign |
|
995
|
|
|
{ |
|
996
|
|
|
$working = 1; |
|
997
|
|
|
$mode = 2; |
|
998
|
|
|
$attr = preg_replace('/^\s*=\s*/', '', $attr); |
|
999
|
|
|
break; |
|
1000
|
|
|
} |
|
1001
|
|
|
|
|
1002
|
|
|
if (preg_match('/^\s+/', $attr)) # valueless |
|
1003
|
|
|
{ |
|
1004
|
|
|
$working = 1; |
|
1005
|
|
|
$mode = 0; |
|
1006
|
|
|
if(false === array_key_exists($attrname, $attrarr)) { |
|
1007
|
|
|
$attrarr[$attrname] = array ('name' => $attrname, 'value' => '', 'whole' => $attrname, 'vless' => 'y'); |
|
1008
|
|
|
} |
|
1009
|
|
|
$attr = preg_replace('/^\s+/', '', $attr); |
|
1010
|
|
|
} |
|
1011
|
|
|
|
|
1012
|
|
|
break; |
|
1013
|
|
|
|
|
1014
|
|
|
case 2 : # attribute value, a URL after href= for instance |
|
1015
|
|
|
|
|
1016
|
|
View Code Duplication |
if (preg_match('%^"([^"]*)"(\s+|/?$)%', $attr, $match)) |
|
1017
|
|
|
# "value" |
|
1018
|
|
|
{ |
|
1019
|
|
|
$thisval = $match[1]; |
|
1020
|
|
|
if ( in_array(strtolower($attrname), $uris) ) |
|
1021
|
|
|
$thisval = VaultPress_kses::wp_kses_bad_protocol($thisval, $allowed_protocols); |
|
1022
|
|
|
|
|
1023
|
|
|
if(false === array_key_exists($attrname, $attrarr)) { |
|
1024
|
|
|
$attrarr[$attrname] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname=\"$thisval\"", 'vless' => 'n'); |
|
1025
|
|
|
} |
|
1026
|
|
|
$working = 1; |
|
1027
|
|
|
$mode = 0; |
|
1028
|
|
|
$attr = preg_replace('/^"[^"]*"(\s+|$)/', '', $attr); |
|
1029
|
|
|
break; |
|
1030
|
|
|
} |
|
1031
|
|
|
|
|
1032
|
|
View Code Duplication |
if (preg_match("%^'([^']*)'(\s+|/?$)%", $attr, $match)) |
|
1033
|
|
|
# 'value' |
|
1034
|
|
|
{ |
|
1035
|
|
|
$thisval = $match[1]; |
|
1036
|
|
|
if ( in_array(strtolower($attrname), $uris) ) |
|
1037
|
|
|
$thisval = VaultPress_kses::wp_kses_bad_protocol($thisval, $allowed_protocols); |
|
1038
|
|
|
|
|
1039
|
|
|
if(false === array_key_exists($attrname, $attrarr)) { |
|
1040
|
|
|
$attrarr[$attrname] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname='$thisval'", 'vless' => 'n'); |
|
1041
|
|
|
} |
|
1042
|
|
|
$working = 1; |
|
1043
|
|
|
$mode = 0; |
|
1044
|
|
|
$attr = preg_replace("/^'[^']*'(\s+|$)/", '', $attr); |
|
1045
|
|
|
break; |
|
1046
|
|
|
} |
|
1047
|
|
|
|
|
1048
|
|
View Code Duplication |
if (preg_match("%^([^\s\"']+)(\s+|/?$)%", $attr, $match)) |
|
1049
|
|
|
# value |
|
1050
|
|
|
{ |
|
1051
|
|
|
$thisval = $match[1]; |
|
1052
|
|
|
if ( in_array(strtolower($attrname), $uris) ) |
|
1053
|
|
|
$thisval = VaultPress_kses::wp_kses_bad_protocol($thisval, $allowed_protocols); |
|
1054
|
|
|
|
|
1055
|
|
|
if(false === array_key_exists($attrname, $attrarr)) { |
|
1056
|
|
|
$attrarr[$attrname] = array ('name' => $attrname, 'value' => $thisval, 'whole' => "$attrname=\"$thisval\"", 'vless' => 'n'); |
|
1057
|
|
|
} |
|
1058
|
|
|
# We add quotes to conform to W3C's HTML spec. |
|
1059
|
|
|
$working = 1; |
|
1060
|
|
|
$mode = 0; |
|
1061
|
|
|
$attr = preg_replace("%^[^\s\"']+(\s+|$)%", '', $attr); |
|
1062
|
|
|
} |
|
1063
|
|
|
|
|
1064
|
|
|
break; |
|
1065
|
|
|
} # switch |
|
1066
|
|
|
|
|
1067
|
|
|
if ($working == 0) # not well formed, remove and try again |
|
1068
|
|
|
{ |
|
1069
|
|
|
$attr = wp_kses_html_error($attr); |
|
1070
|
|
|
$mode = 0; |
|
1071
|
|
|
} |
|
1072
|
|
|
} # while |
|
1073
|
|
|
|
|
1074
|
|
|
if ($mode == 1 && false === array_key_exists($attrname, $attrarr)) |
|
1075
|
|
|
# special case, for when the attribute list ends with a valueless |
|
1076
|
|
|
# attribute like "selected" |
|
1077
|
|
|
$attrarr[$attrname] = array ('name' => $attrname, 'value' => '', 'whole' => $attrname, 'vless' => 'y'); |
|
1078
|
|
|
|
|
1079
|
|
|
return $attrarr; |
|
1080
|
|
|
} |
|
1081
|
|
|
|
|
1082
|
|
|
static function wp_kses_bad_protocol($string, $allowed_protocols) { |
|
1083
|
|
|
$string = wp_kses_no_null($string); |
|
1084
|
|
|
$iterations = 0; |
|
1085
|
|
|
|
|
1086
|
|
|
do { |
|
1087
|
|
|
$original_string = $string; |
|
1088
|
|
|
$string = VaultPress_kses::wp_kses_bad_protocol_once($string, $allowed_protocols); |
|
1089
|
|
|
} while ( $original_string != $string && ++$iterations < 6 ); |
|
1090
|
|
|
|
|
1091
|
|
|
if ( $original_string != $string ) |
|
1092
|
|
|
return ''; |
|
1093
|
|
|
|
|
1094
|
|
|
return $string; |
|
1095
|
|
|
} |
|
1096
|
|
|
|
|
1097
|
|
|
static function wp_kses_bad_protocol_once($string, $allowed_protocols, $count = 1) { |
|
1098
|
|
|
$string2 = preg_split( '/:|�*58;|�*3a;/i', $string, 2 ); |
|
1099
|
|
|
if ( isset($string2[1]) && ! preg_match('%/\?%', $string2[0]) ) { |
|
1100
|
|
|
$string = trim( $string2[1] ); |
|
1101
|
|
|
$protocol = VaultPress_kses::wp_kses_bad_protocol_once2( $string2[0], $allowed_protocols ); |
|
1102
|
|
|
if ( 'feed:' == $protocol ) { |
|
1103
|
|
|
if ( $count > 2 ) |
|
1104
|
|
|
return ''; |
|
1105
|
|
|
$string = VaultPress_kses::wp_kses_bad_protocol_once( $string, $allowed_protocols, ++$count ); |
|
1106
|
|
|
if ( empty( $string ) ) |
|
1107
|
|
|
return $string; |
|
1108
|
|
|
} |
|
1109
|
|
|
$string = $protocol . $string; |
|
1110
|
|
|
} |
|
1111
|
|
|
|
|
1112
|
|
|
return $string; |
|
1113
|
|
|
} |
|
1114
|
|
|
|
|
1115
|
|
|
static function wp_kses_bad_protocol_once2( $string, $allowed_protocols ) { |
|
1116
|
|
|
$string2 = wp_kses_decode_entities($string); |
|
1117
|
|
|
$string2 = preg_replace('/\s/', '', $string2); |
|
1118
|
|
|
$string2 = wp_kses_no_null($string2); |
|
1119
|
|
|
$string2 = strtolower($string2); |
|
1120
|
|
|
|
|
1121
|
|
|
$allowed = false; |
|
1122
|
|
|
foreach ( (array) $allowed_protocols as $one_protocol ) { |
|
1123
|
|
|
if ( strtolower( $one_protocol ) == $string2 ) { |
|
1124
|
|
|
$allowed = true; |
|
1125
|
|
|
break; |
|
1126
|
|
|
} |
|
1127
|
|
|
} |
|
1128
|
|
|
|
|
1129
|
|
|
if ($allowed) |
|
1130
|
|
|
return "$string2:"; |
|
1131
|
|
|
else |
|
1132
|
|
|
return ''; |
|
1133
|
|
|
} |
|
1134
|
|
|
|
|
1135
|
|
|
} |
|
1136
|
|
|
|
|
1137
|
|
|
if ( !function_exists( 'get_available_languages' ) ) { |
|
1138
|
|
|
function get_available_languages( $dir = null ) { |
|
1139
|
|
|
$languages = array(); |
|
1140
|
|
|
foreach( glob( ( is_null( $dir) ? WP_LANG_DIR : $dir ) . '/*.mo' ) as $lang_file ) |
|
1141
|
|
|
if ( false === strpos( $lang_file, 'continents-cities' ) ) |
|
1142
|
|
|
$languages[] = basename($lang_file, '.mo'); |
|
1143
|
|
|
return $languages; |
|
1144
|
|
|
} |
|
1145
|
|
|
} |
|
1146
|
|
|
|
If you define a variable conditionally, it can happen that it is not defined for all execution paths.
Let’s take a look at an example:
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.
Available Fixes
Check for existence of the variable explicitly:
Define a default value for the variable:
Add a value for the missing path: