WordPress.org

Make WordPress Core

Ticket #40015: 40015.diff

File 40015.diff, 9.0 KB (added by stephenharris, 15 months ago)

Decode HTML entities in site name and blog name for MS emails

  • src/wp-admin/includes/ms.php

    diff --git a/src/wp-admin/includes/ms.php b/src/wp-admin/includes/ms.php
    index 254af7f..39fe07d 100644
    a b All at ###SITENAME### 
    315315        $content = str_replace( '###USERNAME###', $current_user->user_login, $content );
    316316        $content = str_replace( '###ADMIN_URL###', esc_url( self_admin_url( 'options.php?adminhash='.$hash ) ), $content );
    317317        $content = str_replace( '###EMAIL###', $value, $content );
    318         $content = str_replace( '###SITENAME###', get_site_option( 'site_name' ), $content );
     318        $content = str_replace( '###SITENAME###', wp_specialchars_decode( get_site_option( 'site_name' ), ENT_QUOTES ), $content );
    319319        $content = str_replace( '###SITEURL###', network_home_url(), $content );
    320320
    321         wp_mail( $value, sprintf( __( '[%s] New Admin Email Address' ), wp_specialchars_decode( get_option( 'blogname' ) ) ), $content );
     321        wp_mail( $value, sprintf( __( '[%s] New Admin Email Address' ), wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ) ), $content );
    322322
    323323        if ( $switched_locale ) {
    324324                restore_previous_locale();
    All at ###SITENAME### 
    400400                $content = str_replace( '###USERNAME###', $current_user->user_login, $content );
    401401                $content = str_replace( '###ADMIN_URL###', esc_url( self_admin_url( 'profile.php?newuseremail=' . $hash ) ), $content );
    402402                $content = str_replace( '###EMAIL###', $_POST['email'], $content);
    403                 $content = str_replace( '###SITENAME###', get_site_option( 'site_name' ), $content );
     403                $content = str_replace( '###SITENAME###', wp_specialchars_decode( get_site_option( 'site_name' ), ENT_QUOTES ), $content );
    404404                $content = str_replace( '###SITEURL###', network_home_url(), $content );
    405405
    406                 wp_mail( $_POST['email'], sprintf( __( '[%s] New Email Address' ), wp_specialchars_decode( get_option( 'blogname' ) ) ), $content );
     406                wp_mail( $_POST['email'], sprintf( __( '[%s] New Email Address' ), wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ) ), $content );
    407407                $_POST['email'] = $current_user->user_email;
    408408
    409409                if ( $switched_locale ) {
  • tests/phpunit/tests/user/multisite.php

    diff --git a/tests/phpunit/tests/user/multisite.php b/tests/phpunit/tests/user/multisite.php
    index f685684..663f087 100644
    a b class Tests_Multisite_User extends WP_UnitTestCase { 
    424424
    425425                $wp_roles->remove_role( $role );
    426426        }
     427
     428
     429        /**
     430         * Ensure blog's admin e-mail change notification emails do not contain encoded HTML entities
     431         * @ticket 40015
     432         */
     433        function test_ms_new_admin_email_notification_html_entities_decoded() {
     434                reset_phpmailer_instance();
     435
     436                $existing_email = get_option( 'admin_email' );
     437                $new_email = 'new-admin-email@test.dev';
     438
     439                // Give the site and blog a name containing HTML entities
     440                update_site_option( 'site_name', ''Test' site's "name" has <html entities> &' );
     441                update_option( 'blogname', ''Test' blog's "name" has <html entities> &' );
     442
     443                update_option_new_admin_email( $existing_email, $new_email );
     444
     445                $mailer = tests_retrieve_phpmailer_instance();
     446
     447                $recipient = $mailer->get_recipient( 'to' );
     448                $email = $mailer->get_sent();
     449
     450                // Assert reciepient is correct
     451                $this->assertSame( $new_email, $recipient->address, 'Admin email change notification recipient not as expected' );
     452
     453                // Assert that HTML entites have been decode in body and subject
     454                $this->assertContains( '\'Test\' site\'s "name" has <html entities> &', $email->body, 'Email body does not contain the decoded HTML entities' );
     455                $this->assertNotContains( '&#039;Test&#039; site&#039;s &quot;name&quot; has &lt;html entities&gt; &amp;', 'Email body does contains HTML entities' );
     456                $this->assertContains( '\'Test\' blog\'s "name" has <html entities> &', $email->subject, 'Email body does not contain the decoded HTML entities' );
     457                $this->assertNotContains( '&#039;Test&#039; blog&#039;s &quot;name&quot; has &lt;html entities&gt; &amp;', $email->subject, $email->subject, 'Email subject does contains HTML entities' );
     458        }
     459
     460        /**
     461         * A notification e-mail should not be sent if the new admin e-mail:
     462         * - Matches thee existing admin email, or
     463         * - is not a valid e-mail, or
     464         *
     465         * @dataProvider data_user_admin_email_notification_emails
     466         */
     467        function test_ms_new_admin_email_notification_not_sent_when_email_invalid( $email, $message ) {
     468                reset_phpmailer_instance();
     469
     470                update_option( 'admin_email', 'existing-email@test.dev' );
     471                update_option_new_admin_email( 'existing-email@test.dev', $email );
     472
     473                $mailer = tests_retrieve_phpmailer_instance();
     474
     475                $this->assertFalse( $mailer->get_sent(), $message );
     476        }
     477
     478        /**
     479         * Data provider for test_ms_new_admin_email_notification_not_sent_when_email_invalid().
     480         *
     481         * @return array {
     482         *     @type array {
     483         *         @type string $email   The new e-mail for admin_email
     484         *         @type string $message An error message to display if the test fails
     485         *     }
     486         * }
     487         */
     488        function data_user_admin_email_notification_emails() {
     489                return array(
     490                        array(
     491                                'existing-email@test.dev',
     492                                'A notification e-mail should not be sent if the current admin e-mail matches the new e-mail',
     493                        ),
     494                        array(
     495                                'not an email',
     496                                'A notification e-mail should not be sent if it is not a valid e-mail',
     497                        )
     498                );
     499        }
     500
     501        /**
     502         * Ensure email change confirmation emails do not contain encoded HTML entities
     503         * @ticket 40015
     504         */
     505        function test_ms_send_confirmation_on_profile_email_html_entities_decoded() {
     506
     507                $old_current = get_current_user_id();
     508                $user_id = self::factory()->user->create( array(
     509                        'role'       => 'subscriber',
     510                        'user_email' => 'old-email@test.dev',
     511                ) );
     512                wp_set_current_user( $user_id );
     513
     514                reset_phpmailer_instance();
     515
     516                // Give the site and blog a name containing HTML entities
     517                update_site_option( 'site_name', '&#039;Test&#039; site&#039;s &quot;name&quot; has &lt;html entities&gt; &amp;' );
     518                update_option( 'blogname', '&#039;Test&#039; blog&#039;s &quot;name&quot; has &lt;html entities&gt; &amp;' );
     519
     520                // Set $_POST['email'] with new e-mail and $_POST['id'] with user's ID.
     521                $_POST['user_id'] = $user_id;
     522                $_POST['email'] = 'new-email@test.dev';
     523                send_confirmation_on_profile_email( );
     524
     525                $mailer = tests_retrieve_phpmailer_instance();
     526
     527                $recipient = $mailer->get_recipient( 'to' );
     528                $email = $mailer->get_sent();
     529
     530                // Assert reciepient is correct
     531                $this->assertSame( 'new-email@test.dev', $recipient->address, 'Admin email change notification recipient not as expected' );
     532
     533                // Assert that HTML entites have been decode in body and subject
     534                $this->assertContains( '\'Test\' site\'s "name" has <html entities> &', $email->body, 'Email body does not contain the decoded HTML entities' );
     535                $this->assertNotContains( '&#039;Test&#039; site&#039;s &quot;name&quot; has &lt;html entities&gt; &amp;', $email->body, 'Email body does contains HTML entities' );
     536                $this->assertContains( '\'Test\' blog\'s "name" has <html entities> &', $email->subject, 'Email body does not contain the decoded HTML entities' );
     537                $this->assertNotContains( '&#039;Test&#039; blog&#039;s &quot;name&quot; has &lt;html entities&gt; &amp;', $email->subject, 'Email subject does contains HTML entities' );
     538
     539                wp_set_current_user( $old_current );
     540        }
     541
     542        /**
     543         * A confirmation e-mail should not be sent if user's new e-mail:
     544         * - Matches their existing email, or
     545         * - is not a valid e-mail, or
     546         * - Matches another user's email
     547         *
     548         * @dataProvider data_user_change_email_confirmation_emails
     549         */
     550        function test_ms_profile_email_confirmation_not_sent_invalid_email( $email, $message ) {
     551
     552                $old_current = get_current_user_id();
     553
     554                $user_id = self::factory()->user->create( array(
     555                        'role'       => 'subscriber',
     556                        'user_email' => 'email@test.dev',
     557                ) );
     558                wp_set_current_user( $user_id );
     559
     560                self::factory()->user->create( array(
     561                        'role'       => 'subscriber',
     562                        'user_email' => 'another-user@test.dev',
     563                ) );
     564
     565                reset_phpmailer_instance();
     566
     567                // Set $_POST['email'] with new e-mail and $_POST['id'] with user's ID.
     568                $_POST['user_id'] = $user_id;
     569                $_POST['email'] = $email;
     570                send_confirmation_on_profile_email();
     571
     572                $mailer = tests_retrieve_phpmailer_instance();
     573
     574                $this->assertFalse( $mailer->get_sent(), $message );
     575
     576                wp_set_current_user( $old_current );
     577        }
     578
     579        /**
     580         * Data provider for test_ms_profile_email_confirmation_not_sent_invalid_email().
     581         *
     582         * @return array {
     583         *     @type array {
     584         *         @type string $email   The user's new e-amil.
     585         *         @type string $message An error message to display if the test fails
     586         *     }
     587         * }
     588         */
     589        function data_user_change_email_confirmation_emails() {
     590                return array(
     591                        array(
     592                                'email@test.dev',
     593                                'Confirmation e-mail should not be sent if it matches the user\'s existing e-mail',
     594                        ),
     595                        array(
     596                                'not an email',
     597                                'Confirmation e-mail should not be sent if it is not a valid e-mail',
     598                        ),
     599                        array(
     600                                'another-user@test.dev',
     601                                'Confirmation e-mail should not be sent if it matches another user\'s e-mail',
     602                        ),
     603                );
     604        }
     605
    427606}
    428607
    429608endif ;