Skip to content

Commit 1684c57

Browse files
committed
fix: Validate oEmbed provider data in constructor with _doing_it_wrong() alert
1 parent f826ddb commit 1684c57

2 files changed

Lines changed: 32 additions & 39 deletions

File tree

src/wp-includes/class-wp-oembed.php

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -221,10 +221,28 @@ public function __construct() {
221221
*
222222
* @since 2.9.0
223223
*
224-
* @param array[] $providers An array of arrays containing data about popular oEmbed providers.
224+
* @param array<string, array{ 0: string, 1?: bool }> $providers An associative array mapping URL patterns to
225+
* provider data. Each value must be an array
226+
* with a provider endpoint URL string at index 0
227+
* and an optional boolean regex flag at index 1.
225228
*/
226229
$this->providers = apply_filters( 'oembed_providers', $providers );
227230

231+
foreach ( $this->providers as $matchmask => $data ) {
232+
if ( ! is_array( $data ) || ! isset( $data[0] ) || ! is_string( $data[0] ) ) {
233+
_doing_it_wrong(
234+
'oembed_providers',
235+
sprintf(
236+
/* translators: %s: The oEmbed provider URL pattern. */
237+
__( 'The oEmbed provider data for %s is malformed. Each provider must be an array with a provider endpoint URL string at index 0 and an optional boolean regex flag at index 1.' ),
238+
'<code>' . esc_html( (string) $matchmask ) . '</code>'
239+
),
240+
'7.1.0'
241+
);
242+
unset( $this->providers[ $matchmask ] );
243+
}
244+
}
245+
228246
// Fix any embeds that contain new lines in the middle of the HTML which breaks wpautop().
229247
add_filter( 'oembed_dataparse', array( $this, '_strip_newlines' ), 10, 3 );
230248
}
@@ -273,9 +291,6 @@ public function get_provider( $url, $args = '' ) {
273291
}
274292

275293
foreach ( $this->providers as $matchmask => $data ) {
276-
if ( ! is_array( $data ) || ! isset( $data[0] ) ) {
277-
continue;
278-
}
279294
$providerurl = $data[0];
280295
$regex = $data[1] ?? false;
281296

tests/phpunit/tests/oembed/wpOembed.php

Lines changed: 13 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -280,31 +280,23 @@ public function test_wp_filter_pre_oembed_result_multisite_restores_state_if_no_
280280
/**
281281
* @ticket 65068
282282
*
283-
* @covers ::get_provider
283+
* @covers WP_oEmbed::__construct
284284
*/
285-
public function test_get_provider_skips_malformed_provider_entries() {
286-
$warnings = array();
287-
288-
$error_handler = function ( $errno, $errstr ) use ( &$warnings ) {
289-
if ( E_WARNING === $errno ) {
290-
$warnings[] = $errstr;
291-
}
292-
return false;
285+
public function test_malformed_provider_triggers_doing_it_wrong_and_is_removed() {
286+
$filter = static function ( $providers ) {
287+
$providers['bad_provider'] = array(
288+
'url' => '#https?://example\.site/.*#i',
289+
'endpoint' => 'https://example.site/api/oembed',
290+
);
291+
return $providers;
293292
};
294293

295-
set_error_handler( $error_handler );
296-
297-
$this->oembed->providers['bad_provider'] = array(
298-
'url' => '#https?://example\.site/.*#i',
299-
'endpoint' => 'https://example.site/api/oembed',
300-
);
301-
302-
$result = $this->oembed->get_provider( 'https://en.wikipedia.org/wiki/Rickrolling' );
303-
304-
restore_error_handler();
294+
add_filter( 'oembed_providers', $filter );
295+
$this->setExpectedIncorrectUsage( 'oembed_providers' );
296+
$oembed = new WP_oEmbed();
297+
remove_filter( 'oembed_providers', $filter );
305298

306-
$this->assertFalse( $result );
307-
$this->assertSame( array(), $warnings, 'PHP warnings were raised: ' . implode( ', ', $warnings ) );
299+
$this->assertArrayNotHasKey( 'bad_provider', $oembed->providers );
308300
}
309301

310302
/**
@@ -313,25 +305,11 @@ public function test_get_provider_skips_malformed_provider_entries() {
313305
* @covers ::get_provider
314306
*/
315307
public function test_get_provider_handles_provider_without_regex_flag() {
316-
$warnings = array();
317-
318-
$error_handler = function ( $errno, $errstr ) use ( &$warnings ) {
319-
if ( E_WARNING === $errno ) {
320-
$warnings[] = $errstr;
321-
}
322-
return false;
323-
};
324-
325-
set_error_handler( $error_handler );
326-
327308
// Provider with only index 0 set (no regex flag) — should default $regex to false.
328309
$this->oembed->providers['https://example.site/*'] = array( 'https://example.site/api/oembed' );
329310

330311
$result = $this->oembed->get_provider( 'https://example.site/video/123' );
331312

332-
restore_error_handler();
333-
334313
$this->assertSame( 'https://example.site/api/oembed', $result );
335-
$this->assertSame( array(), $warnings, 'PHP warnings were raised: ' . implode( ', ', $warnings ) );
336314
}
337315
}

0 commit comments

Comments
 (0)