diff --git a/src/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php b/src/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php
index b89b56cbc0..5317c94c9a 100644
--- a/src/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php
+++ b/src/wp-includes/customize/class-wp-customize-nav-menu-item-setting.php
@@ -639,9 +639,9 @@ class WP_Customize_Nav_Menu_Item_Setting extends WP_Customize_Setting {
$menu_item_value['original_title'] = sanitize_text_field( $menu_item_value['original_title'] );
// Apply the same filters as when calling wp_insert_post().
- $menu_item_value['title'] = apply_filters( 'title_save_pre', $menu_item_value['title'] );
- $menu_item_value['attr_title'] = apply_filters( 'excerpt_save_pre', $menu_item_value['attr_title'] );
- $menu_item_value['description'] = apply_filters( 'content_save_pre', $menu_item_value['description'] );
+ $menu_item_value['title'] = wp_unslash( apply_filters( 'title_save_pre', wp_slash( $menu_item_value['title'] ) ) );
+ $menu_item_value['attr_title'] = wp_unslash( apply_filters( 'excerpt_save_pre', wp_slash( $menu_item_value['attr_title'] ) ) );
+ $menu_item_value['description'] = wp_unslash( apply_filters( 'content_save_pre', wp_slash( $menu_item_value['description'] ) ) );
$menu_item_value['url'] = esc_url_raw( $menu_item_value['url'] );
if ( 'publish' !== $menu_item_value['status'] ) {
@@ -776,7 +776,7 @@ class WP_Customize_Nav_Menu_Item_Setting extends WP_Customize_Setting {
$r = wp_update_nav_menu_item(
$value['nav_menu_term_id'],
$is_placeholder ? 0 : $this->post_id,
- $menu_item_data
+ wp_slash( $menu_item_data )
);
if ( is_wp_error( $r ) ) {
diff --git a/src/wp-includes/nav-menu.php b/src/wp-includes/nav-menu.php
index 9ab678653d..3b878f762b 100644
--- a/src/wp-includes/nav-menu.php
+++ b/src/wp-includes/nav-menu.php
@@ -344,6 +344,9 @@ function wp_update_nav_menu_object( $menu_id = 0, $menu_data = array() ) {
/**
* Save the properties of a menu item or create a new one.
*
+ * The menu-item-title, menu-item-description, and menu-item-attr-title are expected
+ * to be pre-slashed since they are passed directly into wp_insert_post().
+ *
* @since 3.0.0
*
* @param int $menu_id The ID of the menu. Required. If "0", makes the menu item a draft orphan.
diff --git a/tests/phpunit/tests/customize/nav-menu-item-setting.php b/tests/phpunit/tests/customize/nav-menu-item-setting.php
index 3431ef8dfa..41549d03cd 100644
--- a/tests/phpunit/tests/customize/nav-menu-item-setting.php
+++ b/tests/phpunit/tests/customize/nav-menu-item-setting.php
@@ -450,11 +450,11 @@ class Test_WP_Customize_Nav_Menu_Item_Setting extends WP_UnitTestCase {
'menu_item_parent' => 'asdasd',
'position' => -123,
'type' => 'custom',
- 'title' => 'Hi',
+ 'title' => '\o/ o\'o Hi',
'url' => 'javascript:alert(1)',
'target' => '" onclick="',
- 'attr_title' => 'bolded',
- 'description' => 'Hello world',
+ 'attr_title' => '\o/ o\'o bolded',
+ 'description' => '\o/ o\'o Hello world',
'classes' => 'hello " inject="',
'xfn' => 'hello " inject="',
'status' => 'forbidden',
@@ -469,11 +469,11 @@ class Test_WP_Customize_Nav_Menu_Item_Setting extends WP_UnitTestCase {
'menu_item_parent' => 0,
'position' => -123,
'type' => 'customb',
- 'title' => current_user_can( 'unfiltered_html' ) ? 'Hi' : 'HiunfilteredHtml()',
+ 'title' => current_user_can( 'unfiltered_html' ) ? '\o/ o\'o Hi' : '\o/ o\'o HiunfilteredHtml()',
'url' => '',
'target' => 'onclick',
- 'attr_title' => current_user_can( 'unfiltered_html' ) ? 'bolded' : 'boldedunfilteredHtml()',
- 'description' => current_user_can( 'unfiltered_html' ) ? 'Hello world' : 'Hello worldunfilteredHtml()',
+ 'attr_title' => current_user_can( 'unfiltered_html' ) ? '\o/ o\'o bolded' : '\o/ o\'o boldedunfilteredHtml()',
+ 'description' => current_user_can( 'unfiltered_html' ) ? '\o/ o\'o Hello world' : '\o/ o\'o Hello worldunfilteredHtml()',
'classes' => 'hello inject',
'xfn' => 'hello inject',
'status' => 'draft',
@@ -488,7 +488,7 @@ class Test_WP_Customize_Nav_Menu_Item_Setting extends WP_UnitTestCase {
$this->assertEquals( $value, $sanitized[ $key ], "Expected $key to be sanitized." );
}
- $nav_menu_item_id = wp_update_nav_menu_item( $menu_id, 0, array(
+ $nav_menu_item_id = wp_update_nav_menu_item( $menu_id, 0, wp_slash( array(
'menu-item-object-id' => $unsanitized['object_id'],
'menu-item-object' => $unsanitized['object'],
'menu-item-parent-id' => $unsanitized['menu_item_parent'],
@@ -502,7 +502,7 @@ class Test_WP_Customize_Nav_Menu_Item_Setting extends WP_UnitTestCase {
'menu-item-classes' => $unsanitized['classes'],
'menu-item-xfn' => $unsanitized['xfn'],
'menu-item-status' => $unsanitized['status'],
- ) );
+ ) ) );
$post = get_post( $nav_menu_item_id );
$nav_menu_item = wp_setup_nav_menu_item( clone $post );
@@ -549,7 +549,7 @@ class Test_WP_Customize_Nav_Menu_Item_Setting extends WP_UnitTestCase {
'type' => 'post_type',
'object' => 'post',
'object_id' => $second_post_id,
- 'title' => 'Saludos',
+ 'title' => 'Saludos \o/ o\'o',
'status' => 'publish',
'nav_menu_term_id' => $secondary_menu_id,
);