From b66d559e4900dc6f7b6a8092c07627554cd3212d Mon Sep 17 00:00:00 2001 From: Tim Otten Date: Tue, 10 Mar 2020 00:23:45 -0700 Subject: [PATCH] dev/core#1637 - Multiple fixes for Civi/Core/Paths.php For a full write-up, see PR --- Civi/Core/Paths.php | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) diff --git a/Civi/Core/Paths.php b/Civi/Core/Paths.php index 651fb29cdc..9099c3cff9 100644 --- a/Civi/Core/Paths.php +++ b/Civi/Core/Paths.php @@ -210,18 +210,23 @@ class Paths { * @return mixed|string */ public function getPath($value) { + if ($value === NULL || $value === FALSE || $value === '') { + return FALSE; + } + $defaultContainer = self::DEFAULT_PATH; if ($value && $value{0} == '[' && preg_match(';^\[([a-zA-Z0-9\._]+)\]/(.*);', $value, $matches)) { $defaultContainer = $matches[1]; $value = $matches[2]; } - if (empty($value)) { - return FALSE; - } - if ($value === '.') { + + $isDot = $value === '.'; + if ($isDot) { $value = ''; } - return \CRM_Utils_File::absoluteDirectory($value, $this->getVariable($defaultContainer, 'path')); + + $result = \CRM_Utils_File::absoluteDirectory($value, $this->getVariable($defaultContainer, 'path')); + return $isDot ? rtrim($result, '/' . DIRECTORY_SEPARATOR) : $result; } /** @@ -229,6 +234,14 @@ class Paths { * * @param string $value * The file path. The path may begin with a variable, e.g. "[civicrm.files]/upload". + * + * This function was designed for locating files under a given tree, and the + * the result for a straight variable expressions ("[foo.bar]") was not + * originally defined. You may wish to use one of these: + * + * - getVariable('foo.bar', 'url') => Lookup variable by itself + * - getUrl('[foo.bar]/') => Get the variable (normalized with a trailing "/"). + * - getUrl('[foo.bar]/.') => Get the variable (normalized without a trailing "/"). * @param string $preferFormat * The preferred format ('absolute', 'relative'). * The result data may not meet the preference -- if the setting @@ -236,26 +249,26 @@ class Paths { * absolute (regardless of preference). * @param bool|NULL $ssl * NULL to autodetect. TRUE to force to SSL. - * @return mixed|string + * @return FALSE|string + * The URL for $value (string), or FALSE if the $value is not specified. */ public function getUrl($value, $preferFormat = 'relative', $ssl = NULL) { + if ($value === NULL || $value === FALSE || $value === '') { + return FALSE; + } + $defaultContainer = self::DEFAULT_URL; if ($value && $value{0} == '[' && preg_match(';^\[([a-zA-Z0-9\._]+)\](/(.*))$;', $value, $matches)) { $defaultContainer = $matches[1]; - $value = empty($matches[3]) ? '.' : $matches[3]; + $value = $matches[3]; } - if (empty($value)) { - return FALSE; - } - if ($value === '.') { - $value = ''; - } - if (substr($value, 0, 4) == 'http') { + $isDot = $value === '.'; + if (substr($value, 0, 5) === 'http:' || substr($value, 0, 6) === 'https:') { return $value; } - $value = rtrim($this->getVariable($defaultContainer, 'url'), '/') . '/' . $value; + $value = rtrim($this->getVariable($defaultContainer, 'url'), '/') . ($isDot ? '' : "/$value"); if ($preferFormat === 'relative') { $parsed = parse_url($value); -- 2.25.1