Replace substr with cleaner string methods
Use str_starts_with, str_ends_with or string offset where appropriate. This fixes a bug in MimeAnalyzer where the "UTF-16LE" header could not be identified because of wrong constant. This is the exact type of bug that the new functions can avoid. Change-Id: I9f30881e7e895f011db29cf5dcbe43bc4f341062
This commit is contained in:
parent
9c134e2283
commit
676fcf4379
25 changed files with 36 additions and 37 deletions
|
|
@ -135,7 +135,7 @@ function wfImageAuthMain() {
|
|||
$filename = $repo->getZonePath( 'public' ) . $path;
|
||||
// Check to see if the file exists and is not deleted
|
||||
$bits = explode( '!', $name, 2 );
|
||||
if ( substr( $path, 0, 9 ) === '/archive/' && count( $bits ) == 2 ) {
|
||||
if ( str_starts_with( $path, '/archive/' ) && count( $bits ) == 2 ) {
|
||||
$file = $repo->newFromArchiveName( $bits[1], $name );
|
||||
} else {
|
||||
$file = $repo->newFile( $name );
|
||||
|
|
|
|||
|
|
@ -4410,9 +4410,10 @@ class OutputPage extends ContextSource {
|
|||
$media = 'all';
|
||||
}
|
||||
|
||||
if ( substr( $style, 0, 1 ) == '/' ||
|
||||
substr( $style, 0, 5 ) == 'http:' ||
|
||||
substr( $style, 0, 6 ) == 'https:' ) {
|
||||
if ( str_starts_with( $style, '/' ) ||
|
||||
str_starts_with( $style, 'http:' ) ||
|
||||
str_starts_with( $style, 'https:' )
|
||||
) {
|
||||
$url = $style;
|
||||
} else {
|
||||
$config = $this->getConfig();
|
||||
|
|
@ -4463,7 +4464,7 @@ class OutputPage extends ContextSource {
|
|||
} else {
|
||||
$remotePath = $remotePathPrefix;
|
||||
}
|
||||
if ( strpos( $path, $remotePath ) !== 0 || substr( $path, 0, 2 ) === '//' ) {
|
||||
if ( !str_starts_with( $path, $remotePath ) || str_starts_with( $path, '//' ) ) {
|
||||
// - Path is outside wgResourceBasePath, ignore.
|
||||
// - Path is protocol-relative. Fixes T155310. Not supported by RelPath lib.
|
||||
return $path;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ class FauxResponse extends WebResponse {
|
|||
* @param null|int $http_response_code Forces the HTTP response code to the specified value.
|
||||
*/
|
||||
public function header( $string, $replace = true, $http_response_code = null ) {
|
||||
if ( substr( $string, 0, 5 ) == 'HTTP/' ) {
|
||||
if ( str_starts_with( $string, 'HTTP/' ) ) {
|
||||
$parts = explode( ' ', $string, 3 );
|
||||
$this->code = intval( $parts[1] );
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ class PathRouter {
|
|||
if ( !isset( $options['strict'] ) || !$options['strict'] ) {
|
||||
// Unless this is a strict path make sure that the path has a $1
|
||||
if ( strpos( $path, '$1' ) === false ) {
|
||||
if ( substr( $path, -1 ) !== '/' ) {
|
||||
if ( $path[-1] !== '/' ) {
|
||||
$path .= '/';
|
||||
}
|
||||
$path .= '$1';
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class OOUIIconPackModule extends OOUIImageModule {
|
|||
$data[$theme] = [];
|
||||
// Load and merge the JSON data for all "icons-foo" modules
|
||||
foreach ( self::$knownImagesModules as $module ) {
|
||||
if ( substr( $module, 0, 5 ) === 'icons' ) {
|
||||
if ( str_starts_with( $module, 'icons' ) ) {
|
||||
$moreData = $this->readJSONFile( $this->getThemeImagesPath( $theme, $module ) );
|
||||
if ( $moreData ) {
|
||||
$data[$theme] = array_replace_recursive( $data[$theme], $moreData );
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ class OOUIImageModule extends ImageModule {
|
|||
}
|
||||
|
||||
// Extra selectors to allow using the same icons for old-style MediaWiki UI code
|
||||
if ( substr( $module, 0, 5 ) === 'icons' ) {
|
||||
if ( str_starts_with( $module, 'icons' ) ) {
|
||||
$definition['selectorWithoutVariant'] = '.oo-ui-icon-{name}, .mw-ui-icon-{name}:before';
|
||||
$definition['selectorWithVariant'] = '.oo-ui-image-{variant}.oo-ui-icon-{name}, ' .
|
||||
'.mw-ui-icon-{name}-{variant}:before';
|
||||
|
|
|
|||
|
|
@ -405,9 +405,8 @@ class WebRequest {
|
|||
foreach ( (array)$bases as $keyValue => $base ) {
|
||||
// Find the part after $wgArticlePath
|
||||
$base = str_replace( '$1', '', $base );
|
||||
$baseLen = strlen( $base );
|
||||
if ( substr( $path, 0, $baseLen ) == $base ) {
|
||||
$raw = substr( $path, $baseLen );
|
||||
if ( str_starts_with( $path, $base ) ) {
|
||||
$raw = substr( $path, strlen( $base ) );
|
||||
if ( $raw !== '' ) {
|
||||
$matches = [ 'title' => rawurldecode( $raw ) ];
|
||||
if ( $key ) {
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ class UploadDef extends TypeDef {
|
|||
$constant = '';
|
||||
foreach ( get_defined_constants() as $c => $v ) {
|
||||
// @phan-suppress-next-line PhanTypeComparisonFromArray
|
||||
if ( $v === $err && substr( $c, 0, 11 ) === 'UPLOAD_ERR_' ) {
|
||||
if ( $v === $err && str_starts_with( $c, 'UPLOAD_ERR_' ) ) {
|
||||
$constant = " ($c?)";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1792,7 +1792,7 @@ class SwiftFileBackend extends FileBackendStore {
|
|||
}
|
||||
}
|
||||
// Ceph RGW does not use <account> in URLs (OpenStack Swift uses "/v1/<account>")
|
||||
if ( substr( $this->authCreds['storage_url'], -3 ) === '/v1' ) {
|
||||
if ( str_ends_with( $this->authCreds['storage_url'], '/v1' ) ) {
|
||||
$this->isRGW = true; // take advantage of strong consistency in Ceph
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -708,13 +708,13 @@ class MimeAnalyzer implements LoggerAwareInterface {
|
|||
$script_type = null;
|
||||
|
||||
# detect by shebang
|
||||
if ( substr( $head, 0, 2 ) == "#!" ) {
|
||||
if ( str_starts_with( $head, "#!" ) ) {
|
||||
$script_type = "ASCII";
|
||||
} elseif ( substr( $head, 0, 5 ) == "\xef\xbb\xbf#!" ) {
|
||||
} elseif ( str_starts_with( $head, "\xef\xbb\xbf#!" ) ) {
|
||||
$script_type = "UTF-8";
|
||||
} elseif ( substr( $head, 0, 7 ) == "\xfe\xff\x00#\x00!" ) {
|
||||
} elseif ( str_starts_with( $head, "\xfe\xff\x00#\x00!" ) ) {
|
||||
$script_type = "UTF-16BE";
|
||||
} elseif ( substr( $head, 0, 7 ) == "\xff\xfe#\x00!" ) {
|
||||
} elseif ( str_starts_with( $head, "\xff\xfe#\x00!" ) ) {
|
||||
$script_type = "UTF-16LE";
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -134,9 +134,8 @@ abstract class MemcachedBagOStuff extends MediumSpecificBagOStuff {
|
|||
return $key;
|
||||
}
|
||||
|
||||
$prefixLength = strlen( $this->routingPrefix );
|
||||
if ( substr( $key, 0, $prefixLength ) === $this->routingPrefix ) {
|
||||
return substr( $key, $prefixLength );
|
||||
if ( str_starts_with( $key, $this->routingPrefix ) ) {
|
||||
return substr( $key, strlen( $this->routingPrefix ) );
|
||||
}
|
||||
|
||||
return $key;
|
||||
|
|
|
|||
|
|
@ -1062,7 +1062,7 @@ SQL;
|
|||
|
||||
public function streamStatementEnd( &$sql, &$newLine ) {
|
||||
# Allow dollar quoting for function declarations
|
||||
if ( substr( $newLine, 0, 4 ) == '$mw$' ) {
|
||||
if ( str_starts_with( $newLine, '$mw$' ) ) {
|
||||
if ( $this->delimiter ) {
|
||||
$this->delimiter = false;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ class MissingExtensionException extends Exception {
|
|||
* @param string $error Text of error mtime gave
|
||||
*/
|
||||
public function __construct( $path, $error ) {
|
||||
$this->isSkin = substr( $path, -10 ) === "/skin.json";
|
||||
$this->isSkin = str_ends_with( $path, "/skin.json" );
|
||||
$m = [];
|
||||
preg_match( "!/([^/]*)/[^/]*.json$!", $path, $m );
|
||||
if ( $m ) {
|
||||
|
|
|
|||
|
|
@ -1710,7 +1710,7 @@ abstract class UploadBase {
|
|||
# use set/animate to add event-handler attribute to parent
|
||||
if ( ( $strippedElement === 'set' || $strippedElement === 'animate' )
|
||||
&& $stripped === 'attributename'
|
||||
&& substr( $value, 0, 2 ) === 'on'
|
||||
&& str_starts_with( $value, 'on' )
|
||||
) {
|
||||
wfDebug( __METHOD__ . ": Found svg setting event-handler attribute with "
|
||||
. "\"<$strippedElement $stripped='$value'...\" in uploaded file." );
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ class ConvertExtensionToRegistration extends Maintenance {
|
|||
$path = $this->stripPath( $val, $this->dir );
|
||||
// When path starts with tests/parser/ the file would be autodiscovered with
|
||||
// extension registry, so no need to add it to extension.json
|
||||
if ( substr( $path, 0, 13 ) !== 'tests/parser/' || substr( $path, -4 ) !== '.txt' ) {
|
||||
if ( !str_starts_with( $path, 'tests/parser/' ) || !str_ends_with( $path, '.txt' ) ) {
|
||||
$out[$key] = $path;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ class DumpCategoriesAsRdf extends Maintenance {
|
|||
*/
|
||||
public function addDumpHeader( $timestamp ) {
|
||||
$licenseUrl = $this->getConfig()->get( MainConfigNames::RightsUrl );
|
||||
if ( substr( $licenseUrl, 0, 2 ) == '//' ) {
|
||||
if ( str_starts_with( $licenseUrl, '//' ) ) {
|
||||
$licenseUrl = 'https:' . $licenseUrl;
|
||||
}
|
||||
$this->rdfWriter->about( $this->categoriesRdf->getDumpURI() )
|
||||
|
|
|
|||
|
|
@ -195,7 +195,7 @@ class GenerateSitemap extends Maintenance {
|
|||
$dbDomain = WikiMap::getCurrentWikiDbDomain()->getId();
|
||||
$this->fspath = realpath( $fspath ) . DIRECTORY_SEPARATOR;
|
||||
$this->urlpath = $this->getOption( 'urlpath', "" );
|
||||
if ( $this->urlpath !== "" && substr( $this->urlpath, -1 ) !== '/' ) {
|
||||
if ( $this->urlpath !== "" && $this->urlpath[-1] !== '/' ) {
|
||||
$this->urlpath .= '/';
|
||||
}
|
||||
$this->identifier = $this->getOption( 'identifier', $dbDomain );
|
||||
|
|
@ -517,7 +517,7 @@ class GenerateSitemap extends Maintenance {
|
|||
private function indexEntry( $filename ) {
|
||||
return "\t<sitemap>\n" .
|
||||
"\t\t<loc>" . wfGetServerUrl( PROTO_CANONICAL ) .
|
||||
( substr( $this->urlpath, 0, 1 ) === "/" ? "" : "/" ) .
|
||||
( $this->urlpath[0] === "/" ? "" : "/" ) .
|
||||
"{$this->urlpath}$filename</loc>\n" .
|
||||
"\t\t<lastmod>{$this->timestamp}</lastmod>\n" .
|
||||
"\t</sitemap>\n";
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ class ImportSiteScripts extends Maintenance {
|
|||
|
||||
$page = null;
|
||||
foreach ( $result['query']['allpages'] as $page ) {
|
||||
if ( substr( $page['title'], -3 ) === '.js' ) {
|
||||
if ( str_ends_with( $page['title'], '.js' ) ) {
|
||||
strtok( $page['title'], ':' );
|
||||
$pages[] = strtok( '' );
|
||||
}
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@ abstract class Benchmarker extends Maintenance {
|
|||
protected function loadFile( $file ) {
|
||||
$content = file_get_contents( $file );
|
||||
// Detect GZIP compression header
|
||||
if ( substr( $content, 0, 2 ) === "\037\213" ) {
|
||||
if ( str_starts_with( $content, "\037\213" ) ) {
|
||||
$content = gzdecode( $content );
|
||||
}
|
||||
return $content;
|
||||
|
|
|
|||
|
|
@ -99,7 +99,7 @@ class UpdateMediaWiki extends Maintenance {
|
|||
}
|
||||
|
||||
$this->fileHandle = null;
|
||||
if ( substr( $this->getOption( 'schema', '' ), 0, 2 ) === "--" ) {
|
||||
if ( str_starts_with( $this->getOption( 'schema', '' ), '--' ) ) {
|
||||
$this->fatalError( "The --schema option requires a file as an argument.\n" );
|
||||
} elseif ( $this->hasOption( 'schema' ) ) {
|
||||
$file = $this->getOption( 'schema' );
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ foreach ( $lines as $line ) {
|
|||
if ( empty( $line ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( substr( $line, 0, 5 ) === '[BOT]' ) {
|
||||
if ( str_starts_with( $line, '[BOT]' ) ) {
|
||||
continue;
|
||||
}
|
||||
$contributors[$line] = true;
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ class ApiOptionsTest extends ApiTestCase {
|
|||
foreach ( $options as $key => $value ) {
|
||||
if ( isset( $kinds[$key] ) ) {
|
||||
$mapping[$key] = $kinds[$key];
|
||||
} elseif ( substr( $key, 0, 7 ) === 'userjs-' ) {
|
||||
} elseif ( str_starts_with( $key, 'userjs-' ) ) {
|
||||
$mapping[$key] = 'userjs';
|
||||
} else {
|
||||
$mapping[$key] = 'unused';
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ class DatabaseTestHelper extends Database {
|
|||
$check = $m[1];
|
||||
}
|
||||
|
||||
if ( substr( $check, 0, strlen( $this->testName ) ) !== $this->testName ) {
|
||||
if ( !str_starts_with( $check, $this->testName ) ) {
|
||||
throw new MWException( 'function name does not start with test class. ' .
|
||||
$fname . ' vs. ' . $this->testName . '. ' .
|
||||
'Please provide __METHOD__ to database methods.' );
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ class AutoLoaderStructureTest extends MediaWikiIntegrationTestCase {
|
|||
foreach ( $expected as $class => $file ) {
|
||||
// Only prefix $IP if it doesn't have it already.
|
||||
// Generally local classes don't have it, and those from extensions and test suites do.
|
||||
if ( substr( $file, 0, 1 ) != '/' && substr( $file, 1, 1 ) != ':' ) {
|
||||
if ( $file[0] !== '/' && $file[1] !== ':' ) {
|
||||
$filePath = self::fixSlashes( "$IP/$file" );
|
||||
} else {
|
||||
$filePath = self::fixSlashes( $file );
|
||||
|
|
|
|||
|
|
@ -135,7 +135,7 @@ class ExtensionRegistryTest extends MediaWikiUnitTestCase {
|
|||
if ( $before ) {
|
||||
foreach ( $before as $key => $value ) {
|
||||
// mw prefixed globals does not exist normally
|
||||
if ( substr( $key, 0, 2 ) == 'mw' ) {
|
||||
if ( str_starts_with( $key, 'mw' ) ) {
|
||||
$GLOBALS[$key] = $value;
|
||||
} else {
|
||||
$this->setGlobal( $key, $value );
|
||||
|
|
@ -161,7 +161,7 @@ class ExtensionRegistryTest extends MediaWikiUnitTestCase {
|
|||
// Remove mw prefixed globals
|
||||
if ( $before ) {
|
||||
foreach ( $before as $key => $value ) {
|
||||
if ( substr( $key, 0, 2 ) == 'mw' ) {
|
||||
if ( str_starts_with( $key, 'mw' ) ) {
|
||||
unset( $GLOBALS[$key] );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue