Changeset View
Standalone View
src/utils/utils.php
Show First 20 Lines • Show All 1,059 Lines • ▼ Show 20 Lines | if (!is_array($result)) { | ||||
// This will probably fail, but will throw a useful exception. | // This will probably fail, but will throw a useful exception. | ||||
$parser = new PhutilJSONParser(); | $parser = new PhutilJSONParser(); | ||||
$result = $parser->parse($string); | $result = $parser->parse($string); | ||||
} | } | ||||
return $result; | return $result; | ||||
} | } | ||||
/** | |||||
* Decode an INI string. | |||||
* | |||||
* @param string | |||||
* @return mixed | |||||
*/ | |||||
function phutil_ini_decode($string) { | |||||
if (function_exists('parse_ini_string')) { | |||||
$result = @parse_ini_string($string, true); | |||||
} else { | |||||
$tmp = new TempFile('ini'); | |||||
Filesystem::writeFile($tmp, $string); | |||||
$full_path = (string)$tmp; | |||||
$result = @parse_ini_file($full_path, true); | |||||
} | |||||
joshuaspence: Ugly conditional to avoid writing a `TempFile` unnecessarily. | |||||
if ($result === false) { | |||||
throw new Exception('Invalid INI.'); | |||||
epriestleyUnsubmitted Not Done Inline Actions(Would be nice to have the path.) epriestley: (Would be nice to have the path.) | |||||
joshuaspenceAuthorUnsubmitted Not Done Inline ActionsAgreed.... I guess this function is probably overkill. I can't think of a case in which we would be parsing an INI string over an INI file (and parse_ini_file is available in all PHP versions that we support whereas parse_ini_string is only available from PHP 5.3). Maybe I'll just change this to phutil_parse_ini_file which can behave similarly to parse_ini_file but with better exceptions? joshuaspence: Agreed.... I guess this function is probably overkill. I can't think of a case in which we… | |||||
epriestleyUnsubmitted Not Done Inline ActionsOh, right. I think making it file oriented, or adding a $what_are_we_parsing parameter, or throwing some parser-specific exception are all reasonable. Or leave it as-is for now. Although I don't have any specific designs for it, it is nice to have a string-oriented API. epriestley: Oh, right. I think making it file oriented, or adding a `$what_are_we_parsing` parameter, or… | |||||
} | |||||
return $result; | |||||
} | |||||
/** | /** | ||||
* Attempt to censor any plaintext credentials from a string. | * Attempt to censor any plaintext credentials from a string. | ||||
* | * | ||||
* The major use case here is to censor usernames and passwords from command | * The major use case here is to censor usernames and passwords from command | ||||
* output. For example, when `git fetch` fails, the output includes credentials | * output. For example, when `git fetch` fails, the output includes credentials | ||||
* for authenticated HTTP remotes. | * for authenticated HTTP remotes. | ||||
* | * | ||||
* @param string Some block of text. | * @param string Some block of text. | ||||
* @return string A similar block of text, but with credentials that could | * @return string A similar block of text, but with credentials that could | ||||
* be identified censored. | * be identified censored. | ||||
*/ | */ | ||||
function phutil_censor_credentials($string) { | function phutil_censor_credentials($string) { | ||||
return preg_replace(',(?<=://)([^/@\s]+)(?=@|$),', 'xxxxx', $string); | return preg_replace(',(?<=://)([^/@\s]+)(?=@|$),', 'xxxxx', $string); | ||||
} | } | ||||
/** | |||||
* Returns a regular expression which is equivalent to the given glob pattern. | |||||
* | |||||
* This function was adapted from | |||||
* https://github.com/symfony/Finder/blob/master/Glob.php. | |||||
* | |||||
* @param string A glob pattern. | |||||
* @return regex | |||||
*/ | |||||
function phutil_glob_to_regex($glob) { | |||||
joshuaspenceAuthorUnsubmitted Not Done Inline ActionsThis is messy, but I think ultimately we need something like this in order to handle the .editorconfig format properly. EditorConfig uses globs (see fnmatch.js) whereas PHP seems to work better with regular expressions. It might be possible to use fnmatch instead, which is probably cleaner. joshuaspence: This is messy, but I think ultimately we need something like this in order to handle the `. | |||||
$escaping = false; | |||||
$in_curlies = 0; | |||||
$regex = ''; | |||||
for ($i = 0; $i < strlen($glob); $i++) { | |||||
$char = $glob[$i]; | |||||
$next_char = ($i < strlen($glob) - 1) ? $glob[$i + 1] : null; | |||||
if (in_array($char, array('.', '(', ')', '|', '+', '^', '$'))) { | |||||
$regex .= "\\$char"; | |||||
} else if ($char === '*') { | |||||
if ($escaping) { | |||||
$regex .= '\\*'; | |||||
} else { | |||||
if ($next_char === '*') { | |||||
$regex .= '.*'; | |||||
} else { | |||||
$regex .= '[^/]*'; | |||||
} | |||||
} | |||||
} else if ($char === '?') { | |||||
$regex .= $escaping ? '\\?' : '[^/]'; | |||||
} else if ($char === '{') { | |||||
$regex .= $escaping ? '\\{' : '('; | |||||
if (!$escaping) { | |||||
++$in_curlies; | |||||
} | |||||
} else if ($char === '}' && $in_curlies) { | |||||
$regex .= $escaping ? '}' : ')'; | |||||
if (!$escaping) { | |||||
--$in_curlies; | |||||
} | |||||
} else if ($char === ',' && $in_curlies) { | |||||
$regex .= $escaping ? ',' : '|'; | |||||
} else if ($char === '\\') { | |||||
if ($escaping) { | |||||
$regex .= '\\\\'; | |||||
$escaping = false; | |||||
} else { | |||||
$escaping = true; | |||||
} | |||||
continue; | |||||
} else { | |||||
$regex .= $char; | |||||
} | |||||
$escaping = false; | |||||
} | |||||
return '#^'.$regex.'$#'; | |||||
epriestleyUnsubmitted Not Done Inline ActionsThis should probably use \z (end of input) not $ (end of input, or before-newline-at-end-of-input). That is, /^abc$/ matches both "abc" and "abc\n". >>> orbital ~/devtools/arcanist $ php -r 'var_dump(preg_match("/^abc$/", "abc\n"));' int(1) >>> orbital ~/devtools/arcanist $ php -r 'var_dump(preg_match("/^abc\z/", "abc\n"));' int(0) epriestley: This should probably use `\z` (end of input) not `$` (end of input, or before-newline-at-end-of… | |||||
joshuaspenceAuthorUnsubmitted Not Done Inline ActionsYou're probably right... I guess the assumption was that a glob wouldn't contain newlines. joshuaspence: You're probably right... I guess the assumption was that a glob wouldn't contain newlines. | |||||
} |
Ugly conditional to avoid writing a TempFile unnecessarily.