Addressing some PHP 8 incompatibilities

Summary:
Starting with a new instance running PHP 8.2, address all exceptions that come up through some basic browsing/usage.

For `strlen(null)` issues I generally tried to resolve if the value should be non-null at the point of issue, and attempt to address at earlier call-site. There were not many of these that I could determine. In the rest of those cases I would replace with a null-and-strlen check, or use `phutil_nonempty_string` if I was certain the value was a string and it was more convenient.

Hitting all code-paths is challenging, so I would search for `strlen` within radius of files I was modifying and evaluate to address those uses in the same manner.

Notes:
- `AphrontRequest::getStr` only ever returns a string, and is safe to use `phutil_nonempty_string`.
- `PhabricatorEnv::getEnvConfig` can return non-string things so any values coming from there should never use `phutil_nonempty_string`.
- `AphrontRequest::getHTTPHeader` indicates it could return wild so `phutil_nonempty_string` should not be used.
- `AphrontRequest::getURIData` isn't clear if it could return non-string data, so never use `phutil_nonempty_string`.

Refs T13588

Test Plan: I'm running an instance on 8.2 and went through the basic setup/installation, startup and usage, including setup issues and configurations/settings.

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: aklapper, Korvin, epriestley

Maniphest Tasks: T13588

Differential Revision: https://secure.phabricator.com/D21862
This commit is contained in:
Christopher Speck 2023-05-07 18:37:34 -04:00
parent bc6f4786a2
commit f6214f060e
71 changed files with 201 additions and 145 deletions

2
.gitignore vendored
View file

@ -36,6 +36,8 @@
# NPM local packages # NPM local packages
/support/aphlict/server/node_modules/ /support/aphlict/server/node_modules/
/support/aphlict/server/package.json
/support/aphlict/server/package-lock.json
# Places for users to add custom resources. # Places for users to add custom resources.
/resources/cows/custom/* /resources/cows/custom/*

View file

@ -66,7 +66,7 @@ final class AphrontRequest extends Phobject {
} }
public static function parseURILineRange($range, $limit) { public static function parseURILineRange($range, $limit) {
if (!strlen($range)) { if ($range === null || !strlen($range)) {
return null; return null;
} }
@ -448,11 +448,10 @@ final class AphrontRequest extends Phobject {
} }
private function getPrefixedCookieName($name) { private function getPrefixedCookieName($name) {
if (strlen($this->cookiePrefix)) { if ($this->cookiePrefix !== null && strlen($this->cookiePrefix)) {
return $this->cookiePrefix.'_'.$name; return $this->cookiePrefix.'_'.$name;
} else {
return $name;
} }
return $name;
} }
public function getCookie($name, $default = null) { public function getCookie($name, $default = null) {
@ -499,7 +498,7 @@ final class AphrontRequest extends Phobject {
// domain is. This makes setup easier, and we'll tell administrators to // domain is. This makes setup easier, and we'll tell administrators to
// configure a base domain during the setup process. // configure a base domain during the setup process.
$base_uri = PhabricatorEnv::getEnvConfig('phabricator.base-uri'); $base_uri = PhabricatorEnv::getEnvConfig('phabricator.base-uri');
if (!strlen($base_uri)) { if ($base_uri === null || !strlen($base_uri)) {
return new PhutilURI('http://'.$host.'/'); return new PhutilURI('http://'.$host.'/');
} }
@ -956,7 +955,7 @@ final class AphrontRequest extends Phobject {
$submit_cookie = PhabricatorCookies::COOKIE_SUBMIT; $submit_cookie = PhabricatorCookies::COOKIE_SUBMIT;
$submit_key = $this->getCookie($submit_cookie); $submit_key = $this->getCookie($submit_cookie);
if (strlen($submit_key)) { if ($submit_key !== null && strlen($submit_key)) {
$this->clearCookie($submit_cookie); $this->clearCookie($submit_cookie);
$this->submitKey = $submit_key; $this->submitKey = $submit_key;
} }

View file

@ -19,7 +19,7 @@ final class AphrontFileResponse extends AphrontResponse {
} }
public function setDownload($download) { public function setDownload($download) {
if (!strlen($download)) { if ($download === null || !strlen($download)) {
$download = 'untitled'; $download = 'untitled';
} }
$this->download = $download; $this->download = $download;
@ -113,7 +113,8 @@ final class AphrontFileResponse extends AphrontResponse {
$headers[] = array('Content-Length', $content_len); $headers[] = array('Content-Length', $content_len);
} }
if (strlen($this->getDownload())) { $download = $this->getDownload();
if ($download !== null && strlen($download)) {
$headers[] = array('X-Download-Options', 'noopen'); $headers[] = array('X-Download-Options', 'noopen');
$filename = $this->getDownload(); $filename = $this->getDownload();
@ -150,7 +151,7 @@ final class AphrontFileResponse extends AphrontResponse {
$begin = (int)$matches[1]; $begin = (int)$matches[1];
// The "Range" may be "200-299" or "200-", meaning "until end of file". // The "Range" may be "200-299" or "200-", meaning "until end of file".
if (strlen($matches[2])) { if ($matches[2] !== null && strlen($matches[2])) {
$range_end = (int)$matches[2]; $range_end = (int)$matches[2];
$end = $range_end + 1; $end = $range_end + 1;
} else { } else {

View file

@ -21,7 +21,7 @@ final class AphrontWebpageResponse extends AphrontHTMLResponse {
public function buildResponseString() { public function buildResponseString() {
$unexpected_output = $this->getUnexpectedOutput(); $unexpected_output = $this->getUnexpectedOutput();
if (strlen($unexpected_output)) { if ($unexpected_output !== null && strlen($unexpected_output)) {
$style = array( $style = array(
'background: linear-gradient(180deg, #eeddff, #ddbbff);', 'background: linear-gradient(180deg, #eeddff, #ddbbff);',
'white-space: pre-wrap;', 'white-space: pre-wrap;',

View file

@ -89,7 +89,7 @@ final class PhabricatorCookies extends Phobject {
// temporary and clearing it when users log out. // temporary and clearing it when users log out.
$value = $request->getCookie(self::COOKIE_CLIENTID); $value = $request->getCookie(self::COOKIE_CLIENTID);
if (!strlen($value)) { if ($value === null || !strlen($value)) {
$request->setTemporaryCookie( $request->setTemporaryCookie(
self::COOKIE_CLIENTID, self::COOKIE_CLIENTID,
Filesystem::readRandomCharacters(16)); Filesystem::readRandomCharacters(16));

View file

@ -282,7 +282,7 @@ abstract class PhabricatorAuthController extends PhabricatorController {
$viewer, $viewer,
PhabricatorAuthLoginMessageType::MESSAGEKEY); PhabricatorAuthLoginMessageType::MESSAGEKEY);
if (!strlen($text)) { if ($text === null || !strlen($text)) {
return null; return null;
} }

View file

@ -18,7 +18,7 @@ final class PhabricatorAuthRegisterController
$invite = $this->loadInvite(); $invite = $this->loadInvite();
$is_setup = false; $is_setup = false;
if (strlen($account_key)) { if ($account_key !== null && strlen($account_key)) {
$result = $this->loadAccountForRegistrationOrLinking($account_key); $result = $this->loadAccountForRegistrationOrLinking($account_key);
list($account, $provider, $response) = $result; list($account, $provider, $response) = $result;
$is_default = false; $is_default = false;
@ -244,9 +244,9 @@ final class PhabricatorAuthRegisterController
$require_real_name = PhabricatorEnv::getEnvConfig('user.require-real-name'); $require_real_name = PhabricatorEnv::getEnvConfig('user.require-real-name');
$e_username = strlen($value_username) ? null : true; $e_username = phutil_nonempty_string($value_username) ? null : true;
$e_realname = $require_real_name ? true : null; $e_realname = $require_real_name ? true : null;
$e_email = strlen($value_email) ? null : true; $e_email = phutil_nonempty_string($value_email) ? null : true;
$e_password = true; $e_password = true;
$e_captcha = true; $e_captcha = true;
@ -288,7 +288,7 @@ final class PhabricatorAuthRegisterController
if ($can_edit_username) { if ($can_edit_username) {
$value_username = $request->getStr('username'); $value_username = $request->getStr('username');
if (!strlen($value_username)) { if (!phutil_nonempty_string($value_username)) {
$e_username = pht('Required'); $e_username = pht('Required');
$errors[] = pht('Username is required.'); $errors[] = pht('Username is required.');
} else if (!PhabricatorUser::validateUsername($value_username)) { } else if (!PhabricatorUser::validateUsername($value_username)) {
@ -323,7 +323,7 @@ final class PhabricatorAuthRegisterController
if ($can_edit_email) { if ($can_edit_email) {
$value_email = $request->getStr('email'); $value_email = $request->getStr('email');
if (!strlen($value_email)) { if (!phutil_nonempty_string($value_email)) {
$e_email = pht('Required'); $e_email = pht('Required');
$errors[] = pht('Email is required.'); $errors[] = pht('Email is required.');
} else if (!PhabricatorUserEmail::isValidAddress($value_email)) { } else if (!PhabricatorUserEmail::isValidAddress($value_email)) {
@ -339,7 +339,7 @@ final class PhabricatorAuthRegisterController
if ($can_edit_realname) { if ($can_edit_realname) {
$value_realname = $request->getStr('realName'); $value_realname = $request->getStr('realName');
if (!strlen($value_realname) && $require_real_name) { if (!phutil_nonempty_string($value_realname) && $require_real_name) {
$e_realname = pht('Required'); $e_realname = pht('Required');
$errors[] = pht('Real name is required.'); $errors[] = pht('Real name is required.');
} else { } else {

View file

@ -31,7 +31,7 @@ final class PhabricatorAuthStartController
$session_token = $request->getCookie(PhabricatorCookies::COOKIE_SESSION); $session_token = $request->getCookie(PhabricatorCookies::COOKIE_SESSION);
$did_clear = $request->getStr('cleared'); $did_clear = $request->getStr('cleared');
if (strlen($session_token)) { if ($session_token !== null && strlen($session_token)) {
$kind = PhabricatorAuthSessionEngine::getSessionKindFromToken( $kind = PhabricatorAuthSessionEngine::getSessionKindFromToken(
$session_token); $session_token);
switch ($kind) { switch ($kind) {
@ -98,7 +98,7 @@ final class PhabricatorAuthStartController
} }
$next_uri = $request->getStr('next'); $next_uri = $request->getStr('next');
if (!strlen($next_uri)) { if (phutil_nonempty_string($next_uri)) {
if ($this->getDelegatingController()) { if ($this->getDelegatingController()) {
// Only set a next URI from the request path if this controller was // Only set a next URI from the request path if this controller was
// delegated to, which happens when a user tries to view a page which // delegated to, which happens when a user tries to view a page which
@ -112,7 +112,7 @@ final class PhabricatorAuthStartController
} }
if (!$request->isFormPost()) { if (!$request->isFormPost()) {
if (strlen($next_uri)) { if (phutil_nonempty_string($next_uri)) {
PhabricatorCookies::setNextURICookie($request, $next_uri); PhabricatorCookies::setNextURICookie($request, $next_uri);
} }
PhabricatorCookies::setClientIDCookie($request); PhabricatorCookies::setClientIDCookie($request);
@ -226,7 +226,7 @@ final class PhabricatorAuthStartController
$via_header = AphrontRequest::getViaHeaderName(); $via_header = AphrontRequest::getViaHeaderName();
$via_uri = AphrontRequest::getHTTPHeader($via_header); $via_uri = AphrontRequest::getHTTPHeader($via_header);
if (strlen($via_uri)) { if ($via_uri !== null && strlen($via_uri)) {
PhabricatorCookies::setNextURICookie($request, $via_uri, $force = true); PhabricatorCookies::setNextURICookie($request, $via_uri, $force = true);
} }

View file

@ -4,7 +4,7 @@ final class PhabricatorAuthPasswordException
extends Exception { extends Exception {
private $passwordError; private $passwordError;
private $confirmErorr; private $confirmError;
public function __construct( public function __construct(
$message, $message,

View file

@ -74,7 +74,7 @@ abstract class PhabricatorController extends AphrontController {
$session_engine = new PhabricatorAuthSessionEngine(); $session_engine = new PhabricatorAuthSessionEngine();
$phsid = $request->getCookie(PhabricatorCookies::COOKIE_SESSION); $phsid = $request->getCookie(PhabricatorCookies::COOKIE_SESSION);
if (strlen($phsid)) { if ($phsid !== null && strlen($phsid)) {
$session_user = $session_engine->loadUserForSession( $session_user = $session_engine->loadUserForSession(
PhabricatorAuthSession::TYPE_WEB, PhabricatorAuthSession::TYPE_WEB,
$phsid); $phsid);

View file

@ -113,7 +113,7 @@ abstract class CelerityResourceController extends PhabricatorController {
$range = AphrontRequest::getHTTPHeader('Range'); $range = AphrontRequest::getHTTPHeader('Range');
if (strlen($range)) { if ($range !== null && strlen($range)) {
$response->setContentLength(strlen($data)); $response->setContentLength(strlen($data));
list($range_begin, $range_end) = $response->parseHTTPRange($range); list($range_begin, $range_end) = $response->parseHTTPRange($range);

View file

@ -11,7 +11,7 @@ final class PhabricatorBaseURISetupCheck extends PhabricatorSetupCheck {
$host_header = AphrontRequest::getHTTPHeader('Host'); $host_header = AphrontRequest::getHTTPHeader('Host');
if (strpos($host_header, '.') === false) { if (strpos($host_header, '.') === false) {
if (!strlen(trim($host_header))) { if ($host_header === null || !strlen(trim($host_header))) {
$name = pht('No "Host" Header'); $name = pht('No "Host" Header');
$summary = pht('No "Host" header present in request.'); $summary = pht('No "Host" header present in request.');
$message = pht( $message = pht(

View file

@ -53,7 +53,7 @@ final class PhabricatorDaemonsSetupCheck extends PhabricatorSetupCheck {
} }
$expect_user = PhabricatorEnv::getEnvConfig('phd.user'); $expect_user = PhabricatorEnv::getEnvConfig('phd.user');
if (strlen($expect_user)) { if ($expect_user !== null && strlen($expect_user)) {
try { try {
$all_daemons = id(new PhabricatorDaemonLogQuery()) $all_daemons = id(new PhabricatorDaemonLogQuery())

View file

@ -124,7 +124,7 @@ final class PhabricatorPHPPreflightSetupCheck extends PhabricatorSetupCheck {
} }
$open_basedir = ini_get('open_basedir'); $open_basedir = ini_get('open_basedir');
if (strlen($open_basedir)) { if ($open_basedir !== null && strlen($open_basedir)) {
// If `open_basedir` is set, just fatal. It's technically possible for // If `open_basedir` is set, just fatal. It's technically possible for
// us to run with certain values of `open_basedir`, but: we can only // us to run with certain values of `open_basedir`, but: we can only
// raise fatal errors from preflight steps, so we'd have to do this check // raise fatal errors from preflight steps, so we'd have to do this check

View file

@ -122,7 +122,7 @@ abstract class PhabricatorSetupCheck extends Phobject {
$db_cache = new PhabricatorKeyValueDatabaseCache(); $db_cache = new PhabricatorKeyValueDatabaseCache();
try { try {
$value = $db_cache->getKey('phabricator.setup.issue-keys'); $value = $db_cache->getKey('phabricator.setup.issue-keys');
if (!strlen($value)) { if ($value === null || !strlen($value)) {
return null; return null;
} }
return phutil_json_decode($value); return phutil_json_decode($value);

View file

@ -151,19 +151,19 @@ final class PhabricatorStorageSetupCheck extends PhabricatorSetupCheck {
$how_many = 0; $how_many = 0;
if (strlen($access_key)) { if ($access_key !== null && strlen($access_key)) {
$how_many++; $how_many++;
} }
if (strlen($secret_key)) { if ($secret_key !== null && strlen($secret_key)) {
$how_many++; $how_many++;
} }
if (strlen($region)) { if ($region !== null && strlen($region)) {
$how_many++; $how_many++;
} }
if (strlen($endpoint)) { if ($endpoint !== null && strlen($endpoint)) {
$how_many++; $how_many++;
} }

View file

@ -23,7 +23,7 @@ final class PhabricatorWebServerSetupCheck extends PhabricatorSetupCheck {
} }
$base_uri = PhabricatorEnv::getEnvConfig('phabricator.base-uri'); $base_uri = PhabricatorEnv::getEnvConfig('phabricator.base-uri');
if (!strlen($base_uri)) { if ($base_uri === null || !strlen($base_uri)) {
// If `phabricator.base-uri` is not set then we can't really do // If `phabricator.base-uri` is not set then we can't really do
// anything. // anything.
return; return;

View file

@ -85,14 +85,14 @@ final class PhabricatorConfigConsoleController
$rows = array(); $rows = array();
foreach ($versions as $name => $info) { foreach ($versions as $name => $info) {
$branchpoint = $info['branchpoint']; $branchpoint = $info['branchpoint'];
if (strlen($branchpoint)) { if ($branchpoint !== null && strlen($branchpoint)) {
$branchpoint = substr($branchpoint, 0, 12); $branchpoint = substr($branchpoint, 0, 12);
} else { } else {
$branchpoint = null; $branchpoint = null;
} }
$version = $info['hash']; $version = $info['hash'];
if (strlen($version)) { if ($version !== null && strlen($version)) {
$version = substr($version, 0, 12); $version = substr($version, 0, 12);
} else { } else {
$version = pht('Unknown'); $version = pht('Unknown');

View file

@ -837,7 +837,7 @@ final class PhabricatorConfigDatabaseStatusController
$parts = array(); $parts = array();
foreach ($properties as $key => $property) { foreach ($properties as $key => $property) {
if (!strlen($property)) { if ($property === null || !strlen($property)) {
continue; continue;
} }

View file

@ -7,7 +7,7 @@ final class PhabricatorConfigSettingsListController
$viewer = $request->getViewer(); $viewer = $request->getViewer();
$filter = $request->getURIData('filter'); $filter = $request->getURIData('filter');
if (!strlen($filter)) { if ($filter === null || !strlen($filter)) {
$filter = 'settings'; $filter = 'settings';
} }

View file

@ -26,7 +26,7 @@ final class DarkConsoleController extends PhabricatorController {
} }
$visible = $request->getStr('visible'); $visible = $request->getStr('visible');
if (strlen($visible)) { if (phutil_nonempty_string($visible)) {
$this->writeDarkConsoleSetting( $this->writeDarkConsoleSetting(
PhabricatorDarkConsoleVisibleSetting::SETTINGKEY, PhabricatorDarkConsoleVisibleSetting::SETTINGKEY,
(int)$visible); (int)$visible);
@ -34,7 +34,7 @@ final class DarkConsoleController extends PhabricatorController {
} }
$tab = $request->getStr('tab'); $tab = $request->getStr('tab');
if (strlen($tab)) { if (phutil_nonempty_string($tab)) {
$this->writeDarkConsoleSetting( $this->writeDarkConsoleSetting(
PhabricatorDarkConsoleTabSetting::SETTINGKEY, PhabricatorDarkConsoleTabSetting::SETTINGKEY,
$tab); $tab);

View file

@ -114,6 +114,9 @@ final class DarkConsoleCore extends Phobject {
* need to convert it to UTF-8. * need to convert it to UTF-8.
*/ */
private function sanitizeForJSON($data) { private function sanitizeForJSON($data) {
if ($data === null) {
return '<null>';
}
if (is_object($data)) { if (is_object($data)) {
return '<object:'.get_class($data).'>'; return '<object:'.get_class($data).'>';
} else if (is_array($data)) { } else if (is_array($data)) {

View file

@ -55,7 +55,7 @@ final class DiffusionHistoryQueryConduitAPIMethod
$limit = $request->getValue('limit'); $limit = $request->getValue('limit');
if (strlen($against_hash)) { if (strlen($against_hash)) {
$commit_range = "${against_hash}..${commit_hash}"; $commit_range = "{$against_hash}..{$commit_hash}";
} else { } else {
$commit_range = $commit_hash; $commit_range = $commit_hash;
} }

View file

@ -97,19 +97,19 @@ abstract class DiffusionController extends PhabricatorController {
AphrontRequest $request) { AphrontRequest $request) {
$short_name = $request->getURIData('repositoryShortName'); $short_name = $request->getURIData('repositoryShortName');
if (strlen($short_name)) { if ($short_name !== null && strlen($short_name)) {
// If the short name ends in ".git", ignore it. // If the short name ends in ".git", ignore it.
$short_name = preg_replace('/\\.git\z/', '', $short_name); $short_name = preg_replace('/\\.git\z/', '', $short_name);
return $short_name; return $short_name;
} }
$identifier = $request->getURIData('repositoryCallsign'); $identifier = $request->getURIData('repositoryCallsign');
if (strlen($identifier)) { if ($identifier !== null && strlen($identifier)) {
return $identifier; return $identifier;
} }
$id = $request->getURIData('repositoryID'); $id = $request->getURIData('repositoryID');
if (strlen($id)) { if ($id !== null && strlen($id)) {
return (int)$id; return (int)$id;
} }

View file

@ -183,11 +183,11 @@ final class PhabricatorFilesComposeAvatarBuiltinFile
'image/png'); 'image/png');
} }
private static function rgba2gd($rgba) { private static function rgba2gd(array $rgba) {
$r = $rgba[0]; $r = (int)$rgba[0];
$g = $rgba[1]; $g = (int)$rgba[1];
$b = $rgba[2]; $b = (int)$rgba[2];
$a = $rgba[3]; $a = (int)$rgba[3];
$a = (1 - $a) * 255; $a = (1 - $a) * 255;
return ($a << 24) | ($r << 16) | ($g << 8) | $b; return ($a << 24) | ($r << 16) | ($g << 8) | $b;
} }

View file

@ -65,7 +65,7 @@ final class FileAllocateConduitAPIMethod
->executeOne(); ->executeOne();
} }
if (strlen($name) && !$hash && !$file) { if ($name !== null && strlen($name) && !$hash && !$file) {
if ($length > PhabricatorFileStorageEngine::getChunkThreshold()) { if ($length > PhabricatorFileStorageEngine::getChunkThreshold()) {
// If we don't have a hash, but this file is large enough to store in // If we don't have a hash, but this file is large enough to store in
// chunks and thus may be resumable, try to find a partially uploaded // chunks and thus may be resumable, try to find a partially uploaded

View file

@ -29,7 +29,7 @@ final class PhabricatorFileDataController extends PhabricatorFileController {
$request_kind = $request->getURIData('kind'); $request_kind = $request->getURIData('kind');
$is_download = ($request_kind === 'download'); $is_download = ($request_kind === 'download');
if (!strlen($alt) || $main_domain == $alt_domain) { if (($alt === null || !strlen($alt)) || $main_domain == $alt_domain) {
// No alternate domain. // No alternate domain.
$should_redirect = false; $should_redirect = false;
$is_alternate_domain = false; $is_alternate_domain = false;
@ -69,7 +69,7 @@ final class PhabricatorFileDataController extends PhabricatorFileController {
// an initial request for bytes 0-1 of the audio file, and things go south // an initial request for bytes 0-1 of the audio file, and things go south
// if we can't respond with a 206 Partial Content. // if we can't respond with a 206 Partial Content.
$range = $request->getHTTPHeader('range'); $range = $request->getHTTPHeader('range');
if (strlen($range)) { if ($range !== null && strlen($range)) {
list($begin, $end) = $response->parseHTTPRange($range); list($begin, $end) = $response->parseHTTPRange($range);
} }

View file

@ -20,7 +20,7 @@ final class PhabricatorFileLightboxController
return new Aphront404Response(); return new Aphront404Response();
} }
if (strlen($comment)) { if ($comment !== null && strlen($comment)) {
$xactions = array(); $xactions = array();
$xactions[] = id(new PhabricatorFileTransaction()) $xactions[] = id(new PhabricatorFileTransaction())
->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)

View file

@ -311,12 +311,12 @@ final class PhabricatorFileViewController extends PhabricatorFileController {
$file->getStorageHandle()); $file->getStorageHandle());
$custom_alt = $file->getCustomAltText(); $custom_alt = $file->getCustomAltText();
if (strlen($custom_alt)) { if ($custom_alt !== null && strlen($custom_alt)) {
$finfo->addProperty(pht('Custom Alt Text'), $custom_alt); $finfo->addProperty(pht('Custom Alt Text'), $custom_alt);
} }
$default_alt = $file->getDefaultAltText(); $default_alt = $file->getDefaultAltText();
if (strlen($default_alt)) { if ($default_alt !== null && strlen($default_alt)) {
$finfo->addProperty(pht('Default Alt Text'), $default_alt); $finfo->addProperty(pht('Default Alt Text'), $default_alt);
} }

View file

@ -323,7 +323,7 @@ final class PhabricatorJupyterDocumentEngine
} }
$nbformat = idx($data, 'nbformat'); $nbformat = idx($data, 'nbformat');
if (!strlen($nbformat)) { if ($nbformat == null || !strlen($nbformat)) {
throw new Exception( throw new Exception(
pht( pht(
'This document is missing an "nbformat" field. Jupyter notebooks '. 'This document is missing an "nbformat" field. Jupyter notebooks '.

View file

@ -60,12 +60,12 @@ abstract class PhabricatorDocumentRenderingEngine
} }
$encode_setting = $request->getStr('encode'); $encode_setting = $request->getStr('encode');
if (strlen($encode_setting)) { if (phutil_nonempty_string($encode_setting)) {
$engine->setEncodingConfiguration($encode_setting); $engine->setEncodingConfiguration($encode_setting);
} }
$highlight_setting = $request->getStr('highlight'); $highlight_setting = $request->getStr('highlight');
if (strlen($highlight_setting)) { if (phutil_nonempty_string($highlight_setting)) {
$engine->setHighlightingConfiguration($highlight_setting); $engine->setHighlightingConfiguration($highlight_setting);
} }
@ -208,12 +208,12 @@ abstract class PhabricatorDocumentRenderingEngine
$this->activeEngine = $engine; $this->activeEngine = $engine;
$encode_setting = $request->getStr('encode'); $encode_setting = $request->getStr('encode');
if (strlen($encode_setting)) { if (phutil_nonempty_string($encode_setting)) {
$engine->setEncodingConfiguration($encode_setting); $engine->setEncodingConfiguration($encode_setting);
} }
$highlight_setting = $request->getStr('highlight'); $highlight_setting = $request->getStr('highlight');
if (strlen($highlight_setting)) { if (phutil_nonempty_string($highlight_setting)) {
$engine->setHighlightingConfiguration($highlight_setting); $engine->setHighlightingConfiguration($highlight_setting);
} }

View file

@ -31,11 +31,11 @@ final class PhabricatorS3FileStorageEngine
$endpoint = PhabricatorEnv::getEnvConfig('amazon-s3.endpoint'); $endpoint = PhabricatorEnv::getEnvConfig('amazon-s3.endpoint');
$region = PhabricatorEnv::getEnvConfig('amazon-s3.region'); $region = PhabricatorEnv::getEnvConfig('amazon-s3.region');
return (strlen($bucket) && return ($bucket !== null && strlen($bucket) &&
strlen($access_key) && $access_key !== null && strlen($access_key) &&
strlen($secret_key) && $secret_key !== null && strlen($secret_key) &&
strlen($endpoint) && $endpoint !== null && strlen($endpoint) &&
strlen($region)); $region !== null && strlen($region));
} }
@ -57,7 +57,7 @@ final class PhabricatorS3FileStorageEngine
$parts[] = 'phabricator'; $parts[] = 'phabricator';
$instance_name = PhabricatorEnv::getEnvConfig('cluster.instance'); $instance_name = PhabricatorEnv::getEnvConfig('cluster.instance');
if (strlen($instance_name)) { if ($instance_name !== null && strlen($instance_name)) {
$parts[] = $instance_name; $parts[] = $instance_name;
} }

View file

@ -197,7 +197,7 @@ final class PhabricatorEmbedFileRemarkupRule
$alt = $options['alt']; $alt = $options['alt'];
} }
if (!strlen($alt)) { if ($alt === null || !strlen($alt)) {
$alt = $file->getAltText(); $alt = $file->getAltText();
} }
@ -346,6 +346,9 @@ final class PhabricatorEmbedFileRemarkupRule
} }
private function parseDimension($string) { private function parseDimension($string) {
if ($string === null || !strlen($string)) {
return null;
}
$string = trim($string); $string = trim($string);
if (preg_match('/^(?:\d*\\.)?\d+%?$/', $string)) { if (preg_match('/^(?:\d*\\.)?\d+%?$/', $string)) {

View file

@ -49,7 +49,8 @@ final class PhabricatorImageRemarkupRule extends PhutilRemarkupRule {
$args += $defaults; $args += $defaults;
if (!strlen($args['uri'])) { $uri_arg = $args['uri'];
if ($uri_arg === null || !strlen($uri_arg)) {
return $matches[0]; return $matches[0];
} }
@ -57,9 +58,9 @@ final class PhabricatorImageRemarkupRule extends PhutilRemarkupRule {
// validate it more carefully before proxying it, but if whatever the user // validate it more carefully before proxying it, but if whatever the user
// has typed isn't even close, just decline to activate the rule behavior. // has typed isn't even close, just decline to activate the rule behavior.
try { try {
$uri = new PhutilURI($args['uri']); $uri = new PhutilURI($uri_arg);
if (!strlen($uri->getProtocol())) { if ($uri->getProtocol() === null || !strlen($uri->getProtocol())) {
return $matches[0]; return $matches[0];
} }

View file

@ -288,7 +288,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
// update the parent file if a MIME type hasn't been provided. This matters // update the parent file if a MIME type hasn't been provided. This matters
// for large media files like video. // for large media files like video.
$mime_type = idx($params, 'mime-type'); $mime_type = idx($params, 'mime-type');
if (!strlen($mime_type)) { if ($mime_type === null || !strlen($mime_type)) {
$file->setMimeType('application/octet-stream'); $file->setMimeType('application/octet-stream');
} }
@ -856,7 +856,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
// instance identity in the path allows us to distinguish between requests // instance identity in the path allows us to distinguish between requests
// originating from different instances but served through the same CDN. // originating from different instances but served through the same CDN.
$instance = PhabricatorEnv::getEnvConfig('cluster.instance'); $instance = PhabricatorEnv::getEnvConfig('cluster.instance');
if (strlen($instance)) { if ($instance !== null && strlen($instance)) {
$parts[] = '@'.$instance; $parts[] = '@'.$instance;
} }
@ -903,7 +903,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
$parts[] = 'xform'; $parts[] = 'xform';
$instance = PhabricatorEnv::getEnvConfig('cluster.instance'); $instance = PhabricatorEnv::getEnvConfig('cluster.instance');
if (strlen($instance)) { if ($instance !== null && strlen($instance)) {
$parts[] = '@'.$instance; $parts[] = '@'.$instance;
} }
@ -1278,7 +1278,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
public function getAltText() { public function getAltText() {
$alt = $this->getCustomAltText(); $alt = $this->getCustomAltText();
if (strlen($alt)) { if ($alt !== null && strlen($alt)) {
return $alt; return $alt;
} }
@ -1309,7 +1309,7 @@ final class PhabricatorFile extends PhabricatorFileDAO
$parts = array(); $parts = array();
$name = $this->getName(); $name = $this->getName();
if (strlen($name)) { if ($name !== null && strlen($name)) {
$parts[] = $name; $parts[] = $name;
} }

View file

@ -67,7 +67,7 @@ final class PhabricatorGlobalUploadTargetView extends AphrontView {
require_celerity_resource('global-drag-and-drop-css'); require_celerity_resource('global-drag-and-drop-css');
$hint_text = $this->getHintText(); $hint_text = $this->getHintText();
if (!strlen($hint_text)) { if ($hint_text === null || !strlen($hint_text)) {
$hint_text = "\xE2\x87\xAA ".pht('Drop Files to Upload'); $hint_text = "\xE2\x87\xAA ".pht('Drop Files to Upload');
} }

View file

@ -35,7 +35,7 @@ final class HeraldTranscriptPHIDType extends PhabricatorPHIDType {
$id = $xscript->getID(); $id = $xscript->getID();
$handle->setName(pht('Transcript %s', $id)); $handle->setName(pht('Transcript %s', $id));
$handle->setURI("/herald/transcript/${id}/"); $handle->setURI("/herald/transcript/{$id}/");
} }
} }

View file

@ -45,7 +45,7 @@ final class PhabricatorAppSearchEngine
->withUnlisted(false); ->withUnlisted(false);
$name = $saved->getParameter('name'); $name = $saved->getParameter('name');
if (strlen($name)) { if ($name !== null && strlen($name)) {
$query->withNameContains($name); $query->withNameContains($name);
} }

View file

@ -144,7 +144,19 @@ final class PhabricatorNotificationServerRef
} }
public function getURI($to_path = null) { public function getURI($to_path = null) {
$full_path = rtrim($this->getPath(), '/').'/'.ltrim($to_path, '/'); if ($to_path === null || !strlen($to_path)) {
$to_path = '';
} else {
$to_path = '/'.ltrim($to_path, '/');
}
$base_path = $this->getPath();
if ($base_path === null || !strlen($base_path)) {
$base_path = '';
} else {
$base_path = rtrim($base_path, '/');
}
$full_path = $base_path.$to_path;
$uri = id(new PhutilURI('http://'.$this->getHost())) $uri = id(new PhutilURI('http://'.$this->getHost()))
->setProtocol($this->getProtocol()) ->setProtocol($this->getProtocol())
@ -152,7 +164,7 @@ final class PhabricatorNotificationServerRef
->setPath($full_path); ->setPath($full_path);
$instance = PhabricatorEnv::getEnvConfig('cluster.instance'); $instance = PhabricatorEnv::getEnvConfig('cluster.instance');
if (strlen($instance)) { if ($instance !== null && strlen($instance)) {
$uri->replaceQueryParam('instance', $instance); $uri->replaceQueryParam('instance', $instance);
} }
@ -161,7 +173,7 @@ final class PhabricatorNotificationServerRef
public function getWebsocketURI($to_path = null) { public function getWebsocketURI($to_path = null) {
$instance = PhabricatorEnv::getEnvConfig('cluster.instance'); $instance = PhabricatorEnv::getEnvConfig('cluster.instance');
if (strlen($instance)) { if ($instance !== null && strlen($instance)) {
$to_path = $to_path.'~'.$instance.'/'; $to_path = $to_path.'~'.$instance.'/';
} }

View file

@ -92,7 +92,7 @@ final class PhabricatorNotificationServersConfigType
} }
$path = idx($spec, 'path'); $path = idx($spec, 'path');
if ($type == 'admin' && strlen($path)) { if ($type == 'admin' && $path !== null && strlen($path)) {
throw $this->newException( throw $this->newException(
pht( pht(
'Notification server configuration describes an invalid host '. 'Notification server configuration describes an invalid host '.

View file

@ -91,6 +91,10 @@ final class PhabricatorUserProfileImageCacheType
} }
public function isRawCacheDataValid(PhabricatorUser $user, $key, $data) { public function isRawCacheDataValid(PhabricatorUser $user, $key, $data) {
if ($data === null) {
return false;
}
$parts = explode(',', $data, 2); $parts = explode(',', $data, 2);
$version = reset($parts); $version = reset($parts);
return ($version === $this->getCacheVersion($user)); return ($version === $this->getCacheVersion($user));

View file

@ -36,7 +36,12 @@ final class PhabricatorUserLogView extends AphrontView {
$rows = array(); $rows = array();
foreach ($logs as $log) { foreach ($logs as $log) {
$session = substr($log->getSession(), 0, 6); // Events such as "Login Failure" will not have an associated session.
$session = $log->getSession();
if ($session === null) {
$session = '';
}
$session = substr($session, 0, 6);
$actor_phid = $log->getActorPHID(); $actor_phid = $log->getActorPHID();
$user_phid = $log->getUserPHID(); $user_phid = $log->getUserPHID();

View file

@ -104,6 +104,9 @@ final class PhutilSearchQueryCompiler
private function tokenizeQuery($query) { private function tokenizeQuery($query) {
$maximum_bytes = 1024; $maximum_bytes = 1024;
if ($query === null) {
$query = '';
}
$query_bytes = strlen($query); $query_bytes = strlen($query);
if ($query_bytes > $maximum_bytes) { if ($query_bytes > $maximum_bytes) {
throw new PhutilSearchQueryCompilerSyntaxException( throw new PhutilSearchQueryCompilerSyntaxException(

View file

@ -112,10 +112,10 @@ final class PhabricatorApplicationSearchController
$named_query = null; $named_query = null;
$run_query = true; $run_query = true;
$query_key = $this->queryKey; $query_key = $this->queryKey;
if ($this->queryKey == 'advanced') { if ($query_key == 'advanced') {
$run_query = false; $run_query = false;
$query_key = $request->getStr('query'); $query_key = $request->getStr('query');
} else if (!strlen($this->queryKey)) { } else if ($query_key === null || !strlen($query_key)) {
$found_query_data = false; $found_query_data = false;
if ($request->isHTTPGet() || $request->isQuicksand()) { if ($request->isHTTPGet() || $request->isQuicksand()) {
@ -775,7 +775,7 @@ final class PhabricatorApplicationSearchController
$force_nux) { $force_nux) {
// Don't render NUX if the user has clicked away from the default page. // Don't render NUX if the user has clicked away from the default page.
if (strlen($this->getQueryKey())) { if ($this->getQueryKey() !== null && strlen($this->getQueryKey())) {
return null; return null;
} }
@ -1022,7 +1022,7 @@ final class PhabricatorApplicationSearchController
$object_name = pht('%s %s', $object->getMonogram(), $object->getName()); $object_name = pht('%s %s', $object->getMonogram(), $object->getName());
// Likewise, the context object can only be a dashboard. // Likewise, the context object can only be a dashboard.
if (strlen($context_phid)) { if ($context_phid !== null && !strlen($context_phid)) {
$context = id(new PhabricatorDashboardQuery()) $context = id(new PhabricatorDashboardQuery())
->setViewer($viewer) ->setViewer($viewer)
->withPHIDs(array($context_phid)) ->withPHIDs(array($context_phid))

View file

@ -179,7 +179,7 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
$order = $saved->getParameter('order'); $order = $saved->getParameter('order');
$builtin = $query->getBuiltinOrderAliasMap(); $builtin = $query->getBuiltinOrderAliasMap();
if (strlen($order) && isset($builtin[$order])) { if ($order !== null && strlen($order) && isset($builtin[$order])) {
$query->setOrder($order); $query->setOrder($order);
} else { } else {
// If the order is invalid or not available, we choose the first // If the order is invalid or not available, we choose the first
@ -872,7 +872,7 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
protected function readBoolFromRequest( protected function readBoolFromRequest(
AphrontRequest $request, AphrontRequest $request,
$key) { $key) {
if (!strlen($request->getStr($key))) { if (!phutil_nonempty_string($request->getStr($key))) {
return null; return null;
} }
return $request->getBool($key); return $request->getBool($key);
@ -895,7 +895,7 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
* @task dates * @task dates
*/ */
protected function parseDateTime($date_time) { protected function parseDateTime($date_time) {
if (!strlen($date_time)) { if ($date_time === null || !strlen($date_time)) {
return null; return null;
} }
@ -916,7 +916,7 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
$start_str = $saved_query->getParameter($start_key); $start_str = $saved_query->getParameter($start_key);
$start = null; $start = null;
if (strlen($start_str)) { if ($start_str !== null && strlen($start_str)) {
$start = $this->parseDateTime($start_str); $start = $this->parseDateTime($start_str);
if (!$start) { if (!$start) {
$this->addError( $this->addError(
@ -929,7 +929,7 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
$end_str = $saved_query->getParameter($end_key); $end_str = $saved_query->getParameter($end_key);
$end = null; $end = null;
if (strlen($end_str)) { if ($end_str !== null && strlen($end_str)) {
$end = $this->parseDateTime($end_str); $end = $this->parseDateTime($end_str);
if (!$end) { if (!$end) {
$this->addError( $this->addError(
@ -1137,7 +1137,7 @@ abstract class PhabricatorApplicationSearchEngine extends Phobject {
$viewer = $this->requireViewer(); $viewer = $this->requireViewer();
$query_key = $request->getValue('queryKey'); $query_key = $request->getValue('queryKey');
if (!strlen($query_key)) { if ($query_key === null || !strlen($query_key)) {
$saved_query = new PhabricatorSavedQuery(); $saved_query = new PhabricatorSavedQuery();
} else if ($this->isBuiltinQuery($query_key)) { } else if ($this->isBuiltinQuery($query_key)) {
$saved_query = $this->buildSavedQueryFromBuiltin($query_key); $saved_query = $this->buildSavedQueryFromBuiltin($query_key);

View file

@ -135,7 +135,7 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
if ($is_view) { if ($is_view) {
$selected_item = $this->selectViewItem($view_list, $item_id); $selected_item = $this->selectViewItem($view_list, $item_id);
} else { } else {
if (!strlen($item_id)) { if ($item_id === null || !strlen($item_id)) {
$item_id = self::ITEM_MANAGE; $item_id = self::ITEM_MANAGE;
} }
$selected_item = $this->selectEditItem($view_list, $item_id); $selected_item = $this->selectEditItem($view_list, $item_id);
@ -1308,7 +1308,7 @@ abstract class PhabricatorProfileMenuEngine extends Phobject {
// render the default view instead. // render the default view instead.
$selected_view = null; $selected_view = null;
if (strlen($item_id)) { if ($item_id !== null && strlen($item_id)) {
$item_views = $view_list->getViewsWithItemIdentifier($item_id); $item_views = $view_list->getViewsWithItemIdentifier($item_id);
if ($item_views) { if ($item_views) {
$selected_view = head($item_views); $selected_view = head($item_views);

View file

@ -110,7 +110,7 @@ final class PhabricatorProfileMenuItemView
return $this->isExternalLink; return $this->isExternalLink;
} }
public function setIsLabel($is_label) { public function setIsLabel() {
return $this->setSpecialType('label'); return $this->setSpecialType('label');
} }
@ -118,7 +118,7 @@ final class PhabricatorProfileMenuItemView
return $this->isSpecialType('label'); return $this->isSpecialType('label');
} }
public function setIsDivider($is_divider) { public function setIsDivider() {
return $this->setSpecialType('divider'); return $this->setSpecialType('divider');
} }
@ -140,7 +140,7 @@ final class PhabricatorProfileMenuItemView
->setName($this->getName()); ->setName($this->getName());
$uri = $this->getURI(); $uri = $this->getURI();
if (strlen($uri)) { if ($uri !== null && strlen($uri)) {
if ($this->getIsExternalLink()) { if ($this->getIsExternalLink()) {
if (!PhabricatorEnv::isValidURIForLink($uri)) { if (!PhabricatorEnv::isValidURIForLink($uri)) {
$uri = '#'; $uri = '#';
@ -176,7 +176,7 @@ final class PhabricatorProfileMenuItemView
} }
$tooltip = $this->getTooltip(); $tooltip = $this->getTooltip();
if (strlen($tooltip)) { if ($tooltip !== null && strlen($tooltip)) {
$view->setTooltip($tooltip); $view->setTooltip($tooltip);
} }

View file

@ -17,7 +17,7 @@ final class PhabricatorSearchDateField
} }
protected function validateControlValue($value) { protected function validateControlValue($value) {
if (!strlen($value)) { if ($value === null || !strlen($value)) {
return; return;
} }
@ -32,7 +32,7 @@ final class PhabricatorSearchDateField
} }
protected function parseDateTime($value) { protected function parseDateTime($value) {
if (!strlen($value)) { if ($value === null || !strlen($value)) {
return null; return null;
} }

View file

@ -941,7 +941,7 @@ abstract class PhabricatorEditEngine
} }
} else { } else {
$form_key = $request->getURIData('formKey'); $form_key = $request->getURIData('formKey');
if (strlen($form_key)) { if ($form_key !== null && strlen($form_key)) {
$config = $this->loadEditEngineConfigurationWithIdentifier($form_key); $config = $this->loadEditEngineConfigurationWithIdentifier($form_key);
if (!$config) { if (!$config) {
@ -971,14 +971,14 @@ abstract class PhabricatorEditEngine
} }
$page_key = $request->getURIData('pageKey'); $page_key = $request->getURIData('pageKey');
if (!strlen($page_key)) { if ($page_key === null || !strlen($page_key)) {
$pages = $this->getPages($object); $pages = $this->getPages($object);
if ($pages) { if ($pages) {
$page_key = head_key($pages); $page_key = head_key($pages);
} }
} }
if (strlen($page_key)) { if ($page_key !== null && strlen($page_key)) {
$page = $this->selectPage($object, $page_key); $page = $this->selectPage($object, $page_key);
if (!$page) { if (!$page) {
return new Aphront404Response(); return new Aphront404Response();
@ -1169,7 +1169,7 @@ abstract class PhabricatorEditEngine
if ($this->getIsCreate()) { if ($this->getIsCreate()) {
$template = $request->getStr('template'); $template = $request->getStr('template');
if (strlen($template)) { if (phutil_nonempty_string($template)) {
$template_object = $this->newObjectFromIdentifier( $template_object = $this->newObjectFromIdentifier(
$template, $template,
array( array(
@ -1909,7 +1909,7 @@ abstract class PhabricatorEditEngine
$comment_text = $request->getStr('comment'); $comment_text = $request->getStr('comment');
$comment_metadata = $request->getStr('comment_metadata'); $comment_metadata = $request->getStr('comment_metadata');
if (strlen($comment_metadata)) { if (phutil_nonempty_string($comment_metadata)) {
$comment_metadata = phutil_json_decode($comment_metadata); $comment_metadata = phutil_json_decode($comment_metadata);
} }
@ -2009,7 +2009,7 @@ abstract class PhabricatorEditEngine
$xactions[] = $xaction; $xactions[] = $xaction;
} }
if (strlen($comment_text) || !$xactions) { if (($comment_text !== null && strlen($comment_text)) || !$xactions) {
$xactions[] = id(clone $template) $xactions[] = id(clone $template)
->setTransactionType(PhabricatorTransactions::TYPE_COMMENT) ->setTransactionType(PhabricatorTransactions::TYPE_COMMENT)
->setMetadataValue('remarkup.control', $comment_metadata) ->setMetadataValue('remarkup.control', $comment_metadata)

View file

@ -89,6 +89,9 @@ final class PhabricatorEditEngineSubtype
} }
public function hasTagView() { public function hasTagView() {
if ($this->getTagText() === null) {
return false;
}
return (bool)strlen($this->getTagText()); return (bool)strlen($this->getTagText());
} }

View file

@ -418,7 +418,7 @@ abstract class PhabricatorEditField extends Phobject {
} }
$instructions = $this->getControlInstructions(); $instructions = $this->getControlInstructions();
if (strlen($instructions)) { if ($instructions !== null && strlen($instructions)) {
$form->appendRemarkupInstructions($instructions); $form->appendRemarkupInstructions($instructions);
} }

View file

@ -18,7 +18,7 @@ final class PhabricatorTextEditField
$control = new AphrontFormTextControl(); $control = new AphrontFormTextControl();
$placeholder = $this->getPlaceholder(); $placeholder = $this->getPlaceholder();
if (strlen($placeholder)) { if ($placeholder !== null && strlen($placeholder)) {
$control->setPlaceholder($placeholder); $control->setPlaceholder($placeholder);
} }

View file

@ -617,7 +617,7 @@ abstract class PhabricatorApplicationTransactionEditor
return true; return true;
case PhabricatorTransactions::TYPE_SPACE: case PhabricatorTransactions::TYPE_SPACE:
$space_phid = $xaction->getNewValue(); $space_phid = $xaction->getNewValue();
if (!strlen($space_phid)) { if ($space_phid === null || !strlen($space_phid)) {
// If an install has no Spaces or the Spaces controls are not visible // If an install has no Spaces or the Spaces controls are not visible
// to the viewer, we might end up with the empty string here instead // to the viewer, we might end up with the empty string here instead
// of a strict `null`, because some controller just used `getStr()` // of a strict `null`, because some controller just used `getStr()`

View file

@ -39,7 +39,7 @@ final class PhabricatorTypeaheadModularDatasourceController
$parameters = array(); $parameters = array();
$raw_parameters = $request->getStr('parameters'); $raw_parameters = $request->getStr('parameters');
if (strlen($raw_parameters)) { if (phutil_nonempty_string($raw_parameters)) {
try { try {
$parameters = phutil_json_decode($raw_parameters); $parameters = phutil_json_decode($raw_parameters);
} catch (PhutilJSONParserException $ex) { } catch (PhutilJSONParserException $ex) {

View file

@ -28,7 +28,8 @@ abstract class PhabricatorTypeaheadCompositeDatasource
// We only need to do a prefix phase query if there's an actual query // We only need to do a prefix phase query if there's an actual query
// string. If the user didn't type anything, nothing can possibly match it. // string. If the user didn't type anything, nothing can possibly match it.
if (strlen($this->getRawQuery())) { $raw_query = $this->getRawQuery();
if ($raw_query !== null && strlen($raw_query)) {
$phases[] = self::PHASE_PREFIX; $phases[] = self::PHASE_PREFIX;
} }
@ -214,6 +215,9 @@ abstract class PhabricatorTypeaheadCompositeDatasource
if (!$limit) { if (!$limit) {
$limit = count($results); $limit = count($results);
} }
if (!$offset) {
$offset = 0;
}
$results = array_slice($results, $offset, $limit, $preserve_keys = true); $results = array_slice($results, $offset, $limit, $preserve_keys = true);
} }

View file

@ -147,6 +147,9 @@ abstract class PhabricatorTypeaheadDatasource extends Phobject {
} }
public static function tokenizeString($string) { public static function tokenizeString($string) {
if ($string === null) {
return array();
}
$string = phutil_utf8_strtolower($string); $string = phutil_utf8_strtolower($string);
$string = trim($string); $string = trim($string);
if (!strlen($string)) { if (!strlen($string)) {
@ -464,7 +467,7 @@ abstract class PhabricatorTypeaheadDatasource extends Phobject {
// We're looking for a "(" so that a string like "members(q" is identified // We're looking for a "(" so that a string like "members(q" is identified
// and parsed as a function call. This allows us to start generating // and parsed as a function call. This allows us to start generating
// results immediately, before the user fully types out "members(quack)". // results immediately, before the user fully types out "members(quack)".
return (strpos($token, '(') !== false); return ($token !== null && strpos($token, '(') !== false);
} }

View file

@ -229,7 +229,7 @@ final class PhabricatorDatabaseRef
$host = $this->getHost(); $host = $this->getHost();
$port = $this->getPort(); $port = $this->getPort();
if (strlen($port)) { if ($port !== null && strlen($port)) {
return "{$host}:{$port}"; return "{$host}:{$port}";
} }

View file

@ -89,7 +89,7 @@ final class PhabricatorCustomFieldList extends Phobject {
$field_handles = array_select_keys($handles, $phids[$field_key]); $field_handles = array_select_keys($handles, $phids[$field_key]);
$instructions = $field->getInstructionsForEdit(); $instructions = $field->getInstructionsForEdit();
if (strlen($instructions)) { if ($instructions !== null && strlen($instructions)) {
$form->appendRemarkupInstructions($instructions); $form->appendRemarkupInstructions($instructions);
} }

View file

@ -125,7 +125,7 @@ final class PhabricatorEnv extends Phobject {
// If an instance identifier is defined, write it into the environment so // If an instance identifier is defined, write it into the environment so
// it's available to subprocesses. // it's available to subprocesses.
$instance = self::getEnvConfig('cluster.instance'); $instance = self::getEnvConfig('cluster.instance');
if (strlen($instance)) { if ($instance !== null && strlen($instance)) {
putenv('PHABRICATOR_INSTANCE='.$instance); putenv('PHABRICATOR_INSTANCE='.$instance);
$_ENV['PHABRICATOR_INSTANCE'] = $instance; $_ENV['PHABRICATOR_INSTANCE'] = $instance;
} }

View file

@ -77,7 +77,10 @@ function phabricator_form(PhabricatorUser $user, $attributes, $content) {
$is_post = (strcasecmp($http_method, 'POST') === 0); $is_post = (strcasecmp($http_method, 'POST') === 0);
$http_action = idx($attributes, 'action'); $http_action = idx($attributes, 'action');
$is_absolute_uri = preg_match('#^(https?:|//)#', $http_action); $is_absolute_uri = false;
if ($http_action != null) {
$is_absolute_uri = preg_match('#^(https?:|//)#', $http_action);
}
if ($is_post) { if ($is_post) {

View file

@ -135,7 +135,7 @@ final class AphrontTableView extends AphrontView {
$col_classes = array(); $col_classes = array();
foreach ($this->columnClasses as $key => $class) { foreach ($this->columnClasses as $key => $class) {
if (strlen($class)) { if ($class !== null && strlen($class)) {
$col_classes[] = $class; $col_classes[] = $class;
} else { } else {
$col_classes[] = null; $col_classes[] = null;

View file

@ -109,7 +109,7 @@ abstract class AphrontFormControl extends AphrontView {
} }
public function isEmpty() { public function isEmpty() {
return !strlen($this->getValue()); return $this->getValue() === null || !strlen($this->getValue());
} }
public function getSerializedValue() { public function getSerializedValue() {
@ -171,9 +171,8 @@ abstract class AphrontFormControl extends AphrontView {
array('class' => 'aphront-form-input'), array('class' => 'aphront-form-input'),
$this->renderInput()); $this->renderInput());
$error = null; $error = $this->error;
if (strlen($this->getError())) { if ($error !== null && strlen($error)) {
$error = $this->getError();
if ($error === true) { if ($error === true) {
$error = phutil_tag( $error = phutil_tag(
'span', 'span',
@ -185,9 +184,12 @@ abstract class AphrontFormControl extends AphrontView {
array('class' => 'aphront-form-error'), array('class' => 'aphront-form-error'),
$error); $error);
} }
} else {
$error = null;
} }
if (strlen($this->getLabel())) { $label = $this->label;
if ($label !== null && strlen($label)) {
$label = phutil_tag( $label = phutil_tag(
'label', 'label',
array( array(
@ -203,7 +205,8 @@ abstract class AphrontFormControl extends AphrontView {
$custom_class .= ' aphront-form-control-nolabel'; $custom_class .= ' aphront-form-control-nolabel';
} }
if (strlen($this->getCaption())) { $caption = $this->caption;
if ($caption !== null && strlen($caption)) {
$caption = phutil_tag( $caption = phutil_tag(
'div', 'div',
array('class' => 'aphront-form-caption'), array('class' => 'aphront-form-caption'),

View file

@ -67,8 +67,8 @@ final class AphrontFormTokenizerControl extends AphrontFormControl {
} }
$datasource->setViewer($this->getUser()); $datasource->setViewer($this->getUser());
$placeholder = null; $placeholder = $this->placeholder;
if (!strlen($this->placeholder)) { if ($placeholder === null || !strlen($placeholder)) {
$placeholder = $datasource->getPlaceholderText(); $placeholder = $datasource->getPlaceholderText();
} }

View file

@ -97,11 +97,10 @@ final class AphrontSideNavFilterView extends AphrontView {
->setName($name) ->setName($name)
->setType($type); ->setType($type);
if (strlen($icon)) { if ($icon !== null) {
$item->setIcon($icon); $item->setIcon($icon);
} }
if (strlen($key)) { if (strlen($key)) {
$item->setKey($key); $item->setKey($key);
} }
@ -145,7 +144,7 @@ final class AphrontSideNavFilterView extends AphrontView {
public function selectFilter($key, $default = null) { public function selectFilter($key, $default = null) {
$this->selectedFilter = $default; $this->selectedFilter = $default;
if ($this->menu->getItem($key) && strlen($key)) { if ($key !== null && strlen($key) && $this->menu->getItem($key)) {
$this->selectedFilter = $key; $this->selectedFilter = $key;
} }
return $this->selectedFilter; return $this->selectedFilter;

View file

@ -188,7 +188,7 @@ final class PhabricatorStandardPageView extends PhabricatorBarePageView
} }
} }
if (strlen($prefix)) { if ($prefix !== null && strlen($prefix)) {
$title = $prefix.' '.$title; $title = $prefix.' '.$title;
} }

View file

@ -333,7 +333,7 @@ final class PhabricatorMainMenuView extends AphrontView {
$wordmark_text = PhabricatorCustomLogoConfigType::getLogoWordmark(); $wordmark_text = PhabricatorCustomLogoConfigType::getLogoWordmark();
if (!strlen($wordmark_text)) { if ($wordmark_text === null || !strlen($wordmark_text)) {
$wordmark_text = PlatformSymbols::getPlatformServerName(); $wordmark_text = PlatformSymbols::getPlatformServerName();
} }

View file

@ -44,8 +44,8 @@ final class PHUIInfoView extends AphrontTagView {
return $this; return $this;
} }
public function setIsHidden($bool) { public function setIsHidden($is_hidden) {
$this->isHidden = $bool; $this->isHidden = $is_hidden;
return $this; return $this;
} }
@ -147,7 +147,7 @@ final class PHUIInfoView extends AphrontTagView {
} }
$title = $this->title; $title = $this->title;
if ($title || strlen($title)) { if ($title !== null && strlen($title)) {
$title = phutil_tag( $title = phutil_tag(
'h1', 'h1',
array( array(

View file

@ -120,7 +120,7 @@ final class PHUIObjectItemListView extends AphrontTagView {
require_celerity_resource('phui-oi-color-css'); require_celerity_resource('phui-oi-color-css');
$header = null; $header = null;
if (strlen($this->header)) { if ($this->header !== null && strlen($this->header)) {
$header = phutil_tag( $header = phutil_tag(
'h1', 'h1',
array( array(
@ -141,7 +141,7 @@ final class PHUIObjectItemListView extends AphrontTagView {
} }
$items = $this->items; $items = $this->items;
} else if ($this->allowEmptyList) { } else if ($this->getAllowEmptyList()) {
$items = null; $items = null;
} else { } else {
$string = nonempty($this->noDataString, pht('No data.')); $string = nonempty($this->noDataString, pht('No data.'));

View file

@ -97,6 +97,10 @@ final class PHUIObjectItemView extends AphrontTagView {
return $this; return $this;
} }
public function getHeader() {
return $this->header;
}
public function setSubHead($subhead) { public function setSubHead($subhead) {
$this->subhead = $subhead; $this->subhead = $subhead;
return $this; return $this;
@ -122,10 +126,6 @@ final class PHUIObjectItemView extends AphrontTagView {
return $this->titleText; return $this->titleText;
} }
public function getHeader() {
return $this->header;
}
public function addByline($byline) { public function addByline($byline) {
$this->bylines[] = $byline; $this->bylines[] = $byline;
return $this; return $this;
@ -659,8 +659,12 @@ final class PHUIObjectItemView extends AphrontTagView {
$this->getImageIcon()); $this->getImageIcon());
} }
if ($image && (strlen($this->href) || strlen($this->imageHref))) { $image_href = $this->href;
$image_href = ($this->imageHref) ? $this->imageHref : $this->href; if ($image_href === null || !strlen($image_href)) {
$image_href = $this->imageHref;
}
if ($image && $image_href !== null && strlen($image_href)) {
$image = phutil_tag( $image = phutil_tag(
'a', 'a',
array( array(
@ -873,7 +877,7 @@ final class PHUIObjectItemView extends AphrontTagView {
'class' => 'phui-oi-status-icon', 'class' => 'phui-oi-status-icon',
); );
if (strlen($label)) { if ($label !== null && strlen($label)) {
$options['sigil'] = 'has-tooltip'; $options['sigil'] = 'has-tooltip';
$options['meta'] = array('tip' => $label, 'size' => 300); $options['meta'] = array('tip' => $label, 'size' => 300);
} }

View file

@ -105,6 +105,10 @@ final class PHUITagView extends AphrontTagView {
return $this; return $this;
} }
public function getHref() {
return $this->href;
}
public function setClosed($closed) { public function setClosed($closed) {
$this->closed = $closed; $this->closed = $closed;
return $this; return $this;
@ -126,7 +130,7 @@ final class PHUITagView extends AphrontTagView {
} }
protected function getTagName() { protected function getTagName() {
return strlen($this->href) ? 'a' : 'span'; return ($this->href !== null && strlen($this->href)) ? 'a' : 'span';
} }
public function setContextObject($context_object) { public function setContextObject($context_object) {

View file

@ -30,7 +30,7 @@ final class AphrontStackTraceView extends AphrontView {
$relative = $file; $relative = $file;
foreach ($libraries as $library) { foreach ($libraries as $library) {
$root = phutil_get_library_root($library); $root = phutil_get_library_root($library);
if (Filesystem::isDescendant($file, $root)) { if ($file !== null && Filesystem::isDescendant($file, $root)) {
$lib = $library; $lib = $library;
$relative = Filesystem::readablePath($file, $root); $relative = Filesystem::readablePath($file, $root);
break; break;