diff --git a/src/wp-admin/includes/ajax-actions.php b/src/wp-admin/includes/ajax-actions.php index e3016258cd..cc9fa432fc 100644 --- a/src/wp-admin/includes/ajax-actions.php +++ b/src/wp-admin/includes/ajax-actions.php @@ -3405,7 +3405,7 @@ function wp_ajax_update_theme() { ) ); } - $stylesheet = sanitize_key( wp_unslash( $_POST['slug'] ) ); + $stylesheet = preg_replace( '/[^A-z0-9_\-]/', '', wp_unslash( $_POST['slug'] ) ); $status = array( 'update' => 'theme', 'slug' => $stylesheet, @@ -3490,7 +3490,7 @@ function wp_ajax_delete_theme() { ) ); } - $stylesheet = sanitize_key( wp_unslash( $_POST['slug'] ) ); + $stylesheet = preg_replace( '/[^A-z0-9_\-]/', '', wp_unslash( $_POST['slug'] ) ); $status = array( 'delete' => 'theme', 'slug' => $stylesheet, diff --git a/tests/phpunit/data/themedir1/camelCase/index.php b/tests/phpunit/data/themedir1/camelCase/index.php new file mode 100644 index 0000000000..93de08260b --- /dev/null +++ b/tests/phpunit/data/themedir1/camelCase/index.php @@ -0,0 +1,5 @@ +theme_root = DIR_TESTDATA . '/themedir1'; + $this->orig_theme_dir = $GLOBALS['wp_theme_directories']; + + // /themes is necessary as theme.php functions assume /themes is the root if there is only one root. + $GLOBALS['wp_theme_directories'] = array( WP_CONTENT_DIR . '/themes', $this->theme_root ); + + add_filter( 'theme_root', array( $this, 'filter_theme_root' ) ); + add_filter( 'stylesheet_root', array( $this, 'filter_theme_root' ) ); + add_filter( 'template_root', array( $this, 'filter_theme_root' ) ); + + wp_clean_themes_cache(); + unset( $GLOBALS['wp_themes'] ); + } + + function tearDown() { + $GLOBALS['wp_theme_directories'] = $this->orig_theme_dir; + remove_filter( 'theme_root', array( $this, 'filter_theme_root' ) ); + remove_filter( 'stylesheet_root', array( $this, 'filter_theme_root' ) ); + remove_filter( 'template_root', array( $this, 'filter_theme_root' ) ); + wp_clean_themes_cache(); + unset( $GLOBALS['wp_themes'] ); + + parent::tearDown(); + } + + /** + * Replace the normal theme root dir with our pre-made test dir. + */ + public function filter_theme_root() { + return $this->theme_root; + } + + public function test_missing_slug() { + $_POST['_ajax_nonce'] = wp_create_nonce( 'updates' ); + + // Make the request. + try { + $this->_handleAjax( 'update-theme' ); + } catch ( WPAjaxDieContinueException $e ) { + unset( $e ); + } + + // Get the response. + $response = json_decode( $this->_last_response, true ); + + $expected = array( + 'success' => false, + 'data' => array( + 'slug' => '', + 'errorCode' => 'no_theme_specified', + 'errorMessage' => 'No theme specified.', + ), + ); + + $this->assertEqualSets( $expected, $response ); + } + + public function test_missing_capability() { + $_POST['_ajax_nonce'] = wp_create_nonce( 'updates' ); + $_POST['slug'] = 'foo'; + + // Make the request. + try { + $this->_handleAjax( 'update-theme' ); + } catch ( WPAjaxDieContinueException $e ) { + unset( $e ); + } + + // Get the response. + $response = json_decode( $this->_last_response, true ); + + $expected = array( + 'success' => false, + 'data' => array( + 'update' => 'theme', + 'slug' => 'foo', + 'errorMessage' => 'Sorry, you are not allowed to update themes for this site.', + 'newVersion' => '', + ), + ); + + $this->assertEqualSets( $expected, $response ); + } + + public function test_update_theme() { + $this->_setRole( 'administrator' ); + + $_POST['_ajax_nonce'] = wp_create_nonce( 'updates' ); + $_POST['slug'] = 'twentyten'; + + // Make the request. + try { + + // Prevent wp_update_themes() from running. + wp_installing( true ); + $this->_handleAjax( 'update-theme' ); + wp_installing( false ); + + } catch ( WPAjaxDieContinueException $e ) { + unset( $e ); + } + + // Get the response. + $response = json_decode( $this->_last_response, true ); + + $expected = array( + 'success' => false, + 'data' => array( + 'update' => 'theme', + 'slug' => 'twentyten', + 'errorMessage' => 'The theme is at the latest version.', + 'newVersion' => '', + 'debug' => array( 'The theme is at the latest version.' ), + ), + ); + + $this->assertEqualSets( $expected, $response ); + } + + function test_uppercase_theme_slug() { + $this->_setRole( 'administrator' ); + + $_POST['_ajax_nonce'] = wp_create_nonce( 'updates' ); + $_POST['slug'] = 'camelCase'; + + // Make the request. + try { + $this->_handleAjax( 'update-theme' ); + } catch ( WPAjaxDieContinueException $e ) { + unset( $e ); + } + + // Get the response. + $response = json_decode( $this->_last_response, true ); + + $expected = array( + 'success' => false, + 'data' => array( + 'update' => 'theme', + 'slug' => 'camelCase', + 'newVersion' => '', + 'errorMessage' => 'The theme is at the latest version.', + 'debug' => array( 'The theme is at the latest version.' ), + ), + ); + + $this->assertEqualSets( $expected, $response ); + } +}