From cd56c087a4fd41b40de65198d9c6ca5c85a4a6cf Mon Sep 17 00:00:00 2001 From: Brad Jorsch Date: Tue, 28 Apr 2015 16:32:16 -0400 Subject: [PATCH] Protect API metadata keys from FormatMetadata::fetchExtendedMetadata() Bug: T97469 Change-Id: If5d101231ca913621c88e6683f6ef07f6dae1ee8 --- includes/media/FormatMetadata.php | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/includes/media/FormatMetadata.php b/includes/media/FormatMetadata.php index 0c6b6c7271..2ae5af3dfc 100644 --- a/includes/media/FormatMetadata.php +++ b/includes/media/FormatMetadata.php @@ -1604,7 +1604,7 @@ class FormatMetadata extends ContextSource { // This is an API-specific function so it would be cleaner to call it from // outside fetchExtendedMetadata, but this way we don't need to redo the // computation on a cache hit. - $this->sanitizeArrayForXml( $extendedMetadata ); + $this->sanitizeArrayForAPI( $extendedMetadata ); $valueToCache = array( 'data' => $extendedMetadata, 'timestamp' => wfTimestampNow() ); $wgMemc->set( $cacheKey, $valueToCache, $maxCacheTime ); } @@ -1800,17 +1800,16 @@ class FormatMetadata extends ContextSource { /** * Makes sure the given array is a valid API response fragment - * (can be transformed into XML) * @param array $arr */ - protected function sanitizeArrayForXml( &$arr ) { + protected function sanitizeArrayForAPI( &$arr ) { if ( !is_array( $arr ) ) { return; } $counter = 1; foreach ( $arr as $key => &$value ) { - $sanitizedKey = $this->sanitizeKeyForXml( $key ); + $sanitizedKey = $this->sanitizeKeyForAPI( $key ); if ( $sanitizedKey !== $key ) { if ( isset( $arr[$sanitizedKey] ) ) { // Make the sanitized keys hopefully unique. @@ -1824,20 +1823,24 @@ class FormatMetadata extends ContextSource { unset( $arr[$key] ); } if ( is_array( $value ) ) { - $this->sanitizeArrayForXml( $value ); + $this->sanitizeArrayForAPI( $value ); } } + + // Handle API metadata keys (particularly "_type") + $keys = array_filter( array_keys( $arr ), 'ApiResult::isMetadataKey' ); + if ( $keys ) { + ApiResult::setPreserveKeysList( $arr, $keys ); + } } /** - * Turns a string into a valid XML identifier. - * Used to ensure that keys of an associative array in the - * API response do not break the XML formatter. + * Turns a string into a valid API identifier. * @param string $key * @return string * @since 1.23 */ - protected function sanitizeKeyForXml( $key ) { + protected function sanitizeKeyForAPI( $key ) { // drop all characters which are not valid in an XML tag name // a bunch of non-ASCII letters would be valid but probably won't // be used so we take the easy way -- 2.20.1