Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions api.wordpress.org/public_html/translations/core/1.0/index.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
<?php
/**
* WordPress.org Translations API endpoint for WordPress core.
*
* This is a standalone, unauthenticated, stateless API endpoint: WordPress is not loaded,
* so request data is never slashed, and there is no session or nonce infrastructure.
*
* phpcs:disable WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
*
* @package WordPressdotorg\API\Translations
*/

$base_dir = dirname( dirname( dirname( __DIR__ ) ) );
require( $base_dir . '/translations/lib.php' );
Expand All @@ -9,9 +19,18 @@

$version = WP_CORE_LATEST_RELEASE;
if ( isset( $_REQUEST['version'] ) ) {
$version = $_REQUEST['version'];
// This becomes a memcached cache key, which rejects spaces and control characters.
$version = filter_var(
$_REQUEST['version'],
FILTER_VALIDATE_REGEXP,
array(
'options' => array(
'regexp' => '/^[0-9][a-z0-9._-]{0,99}\z/i',
),
)
);
if ( empty( $version ) || ! is_string( $version ) || ! is_numeric( $version[0] ) ) {
header( $_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request' );
http_response_code( 400 );
die( '?version= must be a valid WordPress version' );
}
Comment thread
obenland marked this conversation as resolved.

Expand All @@ -23,7 +42,7 @@
header( 'Access-Control-Allow-Origin: *' );
header( 'Access-Control-Expose-Headers: X-Translations-Count' );
header( 'X-Translations-Count:' . count( $translations ) );
if ( 'HEAD' === $_SERVER['REQUEST_METHOD'] ) {
if ( isset( $_SERVER['REQUEST_METHOD'] ) && 'HEAD' === $_SERVER['REQUEST_METHOD'] ) {
exit;
}

Expand All @@ -32,4 +51,3 @@
echo json_encode( array( 'translations' => $translations ) );

exit;

45 changes: 37 additions & 8 deletions api.wordpress.org/public_html/translations/plugins/1.0/index.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
<?php
/**
* WordPress.org Translations API endpoint for plugins.
*
* This is a standalone, unauthenticated, stateless API endpoint: WordPress is not loaded,
* so request data is never slashed, and there is no session or nonce infrastructure.
*
* phpcs:disable WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
*
* @package WordPressdotorg\API\Translations
*/

$base_dir = dirname( dirname( dirname( __DIR__ ) ) );
require( $base_dir . '/translations/lib.php' );
Expand All @@ -7,14 +17,34 @@
require( $base_dir . '/includes/object-cache.php' );
wp_cache_init();

$slug = isset( $_REQUEST['slug'] ) ? $_REQUEST['slug'] : '';
$version = isset( $_REQUEST['version'] ) ? $_REQUEST['version'] : null;
// These become memcached cache keys, which reject spaces and control characters.
$slug = isset( $_REQUEST['slug'] ) ? filter_var(
$_REQUEST['slug'],
FILTER_VALIDATE_REGEXP,
array(
'options' => array(
'regexp' => '/^[a-z0-9._-]{1,100}\z/i',
),
)
) : '';
$version = isset( $_REQUEST['version'] ) ? filter_var(
$_REQUEST['version'],
FILTER_VALIDATE_REGEXP,
array(
'options' => array(
'regexp' => '/^[a-z0-9._-]{1,100}\z/i',
),
)
) : null;

if ( isset( $_REQUEST['slug'] ) && ! is_string( $slug ) ) {
http_response_code( 400 );
die( '?slug= invalid.' );
}

foreach ( [ 'slug', 'version' ] as $field ) {
if ( $$field && ! is_string( $$field ) ) {
header( $_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request' );
die( "?{$field}= invalid." );
}
if ( isset( $_REQUEST['version'] ) && ! is_string( $version ) ) {
http_response_code( 400 );
die( '?version= invalid.' );
}

$translations = find_all_translations_for_type_and_domain( 'plugin', $slug, $version );
Expand All @@ -24,4 +54,3 @@
echo json_encode( array( 'translations' => $translations ) );

exit;

45 changes: 37 additions & 8 deletions api.wordpress.org/public_html/translations/themes/1.0/index.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
<?php
/**
* WordPress.org Translations API endpoint for themes.
*
* This is a standalone, unauthenticated, stateless API endpoint: WordPress is not loaded,
* so request data is never slashed, and there is no session or nonce infrastructure.
*
* phpcs:disable WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
*
* @package WordPressdotorg\API\Translations
*/

$base_dir = dirname( dirname( dirname( __DIR__ ) ) );
require( $base_dir . '/translations/lib.php' );
Expand All @@ -7,14 +17,34 @@
require( $base_dir . '/includes/object-cache.php' );
wp_cache_init();

$slug = isset( $_REQUEST['slug'] ) ? $_REQUEST['slug'] : '';
$version = isset( $_REQUEST['version'] ) ? $_REQUEST['version'] : null;
// These become memcached cache keys, which reject spaces and control characters.
$slug = isset( $_REQUEST['slug'] ) ? filter_var(
$_REQUEST['slug'],
FILTER_VALIDATE_REGEXP,
array(
'options' => array(
'regexp' => '/^[a-z0-9._-]{1,100}\z/i',
),
)
) : '';
$version = isset( $_REQUEST['version'] ) ? filter_var(
$_REQUEST['version'],
FILTER_VALIDATE_REGEXP,
array(
'options' => array(
'regexp' => '/^[a-z0-9._-]{1,100}\z/i',
),
)
) : null;

if ( isset( $_REQUEST['slug'] ) && ! is_string( $slug ) ) {
http_response_code( 400 );
die( '?slug= invalid.' );
}

foreach ( [ 'slug', 'version' ] as $field ) {
if ( $$field && ! is_string( $$field ) ) {
header( $_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request' );
die( "?{$field}= invalid." );
}
if ( isset( $_REQUEST['version'] ) && ! is_string( $version ) ) {
http_response_code( 400 );
die( '?version= invalid.' );
}

$translations = find_all_translations_for_type_and_domain( 'theme', $slug, $version );
Expand All @@ -24,4 +54,3 @@
echo json_encode( array( 'translations' => $translations ) );

exit;