PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-beta
Jetpack – WP Security, Backup, Speed, & Growth v16.3-beta
16.3-beta 16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 All 507 releases
← All changes | jetpack_vendor/automattic/jetpack-sync/src/modules/class-themes.php +32 -27 12.5.2 → 16.3-beta View file →
@@ -6,8 +6,12 @@
6 6 */
7 7
8 8 namespace Automattic\Jetpack\Sync\Modules;
9 9
10 +if ( ! defined( 'ABSPATH' ) ) {
11 + exit( 0 );
12 +}
13 +
10 14 /**
11 15 * Class to handle sync for themes.
12 16 */
13 17 class Themes extends Module {
@@ -62,10 +66,8 @@
62 66 * Sync handler for a widget edit.
63 67 *
64 68 * @access public
65 69 *
66 - * @todo Implement nonce verification
67 - *
68 70 * @param array $instance The current widget instance's settings.
69 71 * @param array $new_instance Array of new widget settings.
70 72 * @param array $old_instance Array of old widget settings.
71 73 * @param \WP_Widget $widget_object The current widget instance.
@@ -76,9 +78,9 @@
76 78 return $instance;
77 79 }
78 80
79 81 // Don't trigger sync action if this is an ajax request, because Customizer makes them during preview before saving changes.
80 - // phpcs:disable WordPress.Security.NonceVerification.Missing
82 + // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Not doing anything with or in response to the $_POST data. We're only using $_POST['customized'] to early return if this is an ajax request from Customizer.
81 83 if ( defined( 'DOING_AJAX' ) && DOING_AJAX && isset( $_POST['customized'] ) ) {
82 84 return $instance;
83 85 }
84 86
@@ -84,9 +86,9 @@
84 86
85 87 $widget = array(
86 88 'name' => $widget_object->name,
87 89 'id' => $widget_object->id,
88 - 'title' => isset( $new_instance['title'] ) ? $new_instance['title'] : '',
90 + 'title' => $new_instance['title'] ?? '',
89 91 );
90 92 /**
91 93 * Trigger action to alert $callable sync listener that a widget was edited.
92 94 *
@@ -184,9 +186,9 @@
184 186 public function detect_theme_edit( $redirect_url ) {
185 187 $url = wp_parse_url( admin_url( $redirect_url ) );
186 188 $theme_editor_url = wp_parse_url( admin_url( 'theme-editor.php' ) );
187 189
188 - if ( $theme_editor_url['path'] !== $url['path'] ) {
190 + if ( ! isset( $url['query'] ) || $theme_editor_url['path'] !== $url['path'] ) {
189 191 return $redirect_url;
190 192 }
191 193
192 194 $query_params = array();
@@ -191,9 +193,9 @@
191 193
192 194 $query_params = array();
193 195 wp_parse_str( $url['query'], $query_params );
194 196 if (
195 - ! isset( $_POST['newcontent'] ) ||
197 + ! isset( $_POST['newcontent'] ) || // phpcs:ignore WordPress.Security.NonceVerification.Missing -- 'wp_redirect' gets fired for a lot of things. We're only using $_POST['newcontent'] to limit action to redirects from theme edits, we're not doing anything with or in response to the post itself.
196 198 ! isset( $query_params['file'] ) ||
197 199 ! isset( $query_params['theme'] ) ||
198 200 ! isset( $query_params['updated'] )
199 201 ) {
@@ -225,31 +227,30 @@
225 227 *
226 228 * @todo Refactor to use WP_Filesystem instead of fopen()/fclose().
227 229 */
228 230 public function theme_edit_ajax() {
229 - $args = wp_unslash( $_POST );
230 -
231 - if ( empty( $args['theme'] ) ) {
231 + // This validation is based on wp_edit_theme_plugin_file().
232 + if ( empty( $_POST['theme'] ) ) {
232 233 return;
233 234 }
234 235
235 - if ( empty( $args['file'] ) ) {
236 + if ( empty( $_POST['file'] ) ) {
236 237 return;
237 238 }
238 - $file = $args['file'];
239 + $file = wp_unslash( $_POST['file'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated manually just after.
239 240 if ( 0 !== validate_file( $file ) ) {
240 241 return;
241 242 }
242 243
243 - if ( ! isset( $args['newcontent'] ) ) {
244 + if ( ! isset( $_POST['newcontent'] ) ) {
244 245 return;
245 246 }
246 247
247 - if ( ! isset( $args['nonce'] ) ) {
248 + if ( ! isset( $_POST['nonce'] ) ) {
248 249 return;
249 250 }
250 251
251 - $stylesheet = $args['theme'];
252 + $stylesheet = wp_unslash( $_POST['theme'] ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated manually just after.
252 253 if ( 0 !== validate_file( $stylesheet ) ) {
253 254 return;
254 255 }
255 256
@@ -261,9 +262,9 @@
261 262 if ( ! $theme->exists() ) {
262 263 return;
263 264 }
264 265
265 - if ( ! wp_verify_nonce( $args['nonce'], 'edit-theme_' . $stylesheet . '_' . $file ) ) {
266 + if ( ! wp_verify_nonce( $_POST['nonce'], 'edit-theme_' . $stylesheet . '_' . $file ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput -- WP core doesn't pre-sanitize nonces either.
266 267 return;
267 268 }
268 269
269 270 if ( $theme->errors() && 'theme_no_stylesheet' === $theme->errors()->get_error_code() ) {
@@ -382,8 +383,9 @@
382 383 return;
383 384 }
384 385
385 386 if ( 'install' === $details['action'] ) {
387 + // @phan-suppress-next-line PhanUndeclaredMethod -- Checked above. See also https://github.com/phan/phan/issues/1204.
386 388 $theme = $upgrader->theme_info();
387 389 if ( ! $theme instanceof \WP_Theme ) {
388 390 return;
389 391 }
@@ -510,19 +512,25 @@
510 512 *
511 513 * @access public
512 514 *
513 515 * @param array $config Full sync configuration for this sync module.
516 + * @param array $status This module Full Sync status.
514 517 * @param int $send_until The timestamp until the current request can send.
515 - * @param array $state This module Full Sync status.
518 + * @param int $started The timestamp when the full sync started.
516 519 *
517 520 * @return array This module Full Sync status.
518 521 */
519 - public function send_full_sync_actions( $config, $send_until, $state ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
522 + public function send_full_sync_actions( $config, $status, $send_until, $started ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
520 523 // we call this instead of do_action when sending immediately.
521 - $this->send_action( 'jetpack_full_sync_theme_data', array( true ) );
524 + $result = $this->send_action( 'jetpack_full_sync_theme_data', array( true ) );
522 525
523 - // The number of actions enqueued, and next module state (true == done).
524 - return array( 'finished' => true );
526 + if ( is_wp_error( $result ) ) {
527 + $status['error'] = true;
528 + return $status;
529 + }
530 + $status['finished'] = true;
531 + $status['sent'] = $status['total'];
532 + return $status;
525 533 }
526 534
527 535 /**
528 536 * Retrieve an estimated number of actions that will be enqueued.
@@ -529,9 +537,9 @@
529 537 *
530 538 * @access public
531 539 *
532 540 * @param array $config Full sync configuration for this sync module.
533 - * @return array Number of items yet to be enqueued.
541 + * @return int Number of items yet to be enqueued.
534 542 */
535 543 public function estimate_full_sync_actions( $config ) { // phpcs:ignore VariableAnalysis.CodeAnalysis.VariableAnalysis.UnusedVariable
536 544 return 1;
537 545 }
@@ -736,22 +744,20 @@
736 744 }
737 745
738 746 $moved_to_inactive_ids = array();
739 747 $moved_to_sidebar = array();
748 + $new_inactive_widgets = $new_value['wp_inactive_widgets'] ?? array();
740 749
741 750 foreach ( $new_value as $sidebar => $new_widgets ) {
742 751 if ( in_array( $sidebar, array( 'array_version', 'wp_inactive_widgets' ), true ) ) {
743 752 continue;
744 753 }
745 - $old_widgets = isset( $old_value[ $sidebar ] )
746 - ? $old_value[ $sidebar ]
747 - : array();
754 + $old_widgets = $old_value[ $sidebar ] ?? array();
748 755
749 756 if ( ! is_array( $new_widgets ) ) {
750 757 $new_widgets = array();
751 758 }
752 -
753 - $moved_to_inactive_recently = $this->sync_remove_widgets_from_sidebar( $new_widgets, $old_widgets, $sidebar, $new_value['wp_inactive_widgets'] );
759 + $moved_to_inactive_recently = $this->sync_remove_widgets_from_sidebar( $new_widgets, $old_widgets, $sidebar, $new_inactive_widgets );
754 760 $moved_to_inactive_ids = array_merge( $moved_to_inactive_ids, $moved_to_inactive_recently );
755 761
756 762 $moved_to_sidebar_recently = $this->sync_add_widgets_to_sidebar( $new_widgets, $old_widgets, $sidebar );
757 763 $moved_to_sidebar = array_merge( $moved_to_sidebar, $moved_to_sidebar_recently );
@@ -872,6 +878,5 @@
872 878 }
873 879
874 880 return array( $this->get_theme_info() );
875 881 }
876 -
877 882 }