Make WordPress Core

Changeset 40632


Ignore:
Timestamp:
05/11/2017 07:14:55 PM (7 years ago)
Author:
swissspidy
Message:

Mail: Ensure entities are decoded in email change notifications on Multisite.

Adds new tests to ensure this bug does not pop up again.

Props stephenharris.
Fixes #40015.

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/includes/ms.php

    r40579 r40632  
    326326    $content = str_replace( '###ADMIN_URL###', esc_url( self_admin_url( 'options.php?adminhash='.$hash ) ), $content );
    327327    $content = str_replace( '###EMAIL###', $value, $content );
    328     $content = str_replace( '###SITENAME###', get_site_option( 'site_name' ), $content );
     328    $content = str_replace( '###SITENAME###', wp_specialchars_decode( get_site_option( 'site_name' ), ENT_QUOTES ), $content );
    329329    $content = str_replace( '###SITEURL###', network_home_url(), $content );
    330330
    331     wp_mail( $value, sprintf( __( '[%s] New Admin Email Address' ), wp_specialchars_decode( get_option( 'blogname' ) ) ), $content );
     331    wp_mail( $value, sprintf( __( '[%s] New Admin Email Address' ), wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ) ), $content );
    332332
    333333    if ( $switched_locale ) {
     
    411411        $content = str_replace( '###ADMIN_URL###', esc_url( self_admin_url( 'profile.php?newuseremail=' . $hash ) ), $content );
    412412        $content = str_replace( '###EMAIL###', $_POST['email'], $content);
    413         $content = str_replace( '###SITENAME###', get_site_option( 'site_name' ), $content );
     413        $content = str_replace( '###SITENAME###', wp_specialchars_decode( get_site_option( 'site_name' ), ENT_QUOTES ), $content );
    414414        $content = str_replace( '###SITEURL###', network_home_url(), $content );
    415415
    416         wp_mail( $_POST['email'], sprintf( __( '[%s] New Email Address' ), wp_specialchars_decode( get_option( 'blogname' ) ) ), $content );
     416        wp_mail( $_POST['email'], sprintf( __( '[%s] New Email Address' ), wp_specialchars_decode( get_option( 'blogname' ), ENT_QUOTES ) ), $content );
    417417        $_POST['email'] = $current_user->user_email;
    418418
  • trunk/tests/phpunit/tests/user/multisite.php

    r39082 r40632  
    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
Note: See TracChangeset for help on using the changeset viewer.