1061
* Decode an INI string.
1066
function phutil_ini_decode($string) {
1068
$trap = new PhutilErrorTrap();
1071
if (!function_exists('parse_ini_string')) {
1072
throw new PhutilMethodNotImplementedException(
1074
'%s is not compatible with your version of PHP (%s). This function '.
1075
'is only supported on PHP versions newer than 5.3.0.',
1080
$results = @parse_ini_string($string, true, INI_SCANNER_RAW);
1082
if ($results === false) {
1083
throw new PhutilINIParserException(trim($trap->getErrorsAsString()));
1086
foreach ($results as $section => $result) {
1087
if (!is_array($result)) {
1088
// We JSON decode the value in ordering to perform the following
1091
// - `'true'` => `true`
1092
// - `'false'` => `false`
1093
// - `'123'` => `123`
1094
// - `'1.234'` => `1.234`
1096
$result = json_decode($result, true);
1098
if ($result !== null && !is_array($result)) {
1099
$results[$section] = $result;
1105
foreach ($result as $key => $value) {
1106
$value = json_decode($value, true);
1108
if ($value !== null && !is_array($value)) {
1109
$results[$section][$key] = $value;
1113
} catch (Exception $ex) {
1061
1124
* Attempt to censor any plaintext credentials from a string.
1063
1126
* The major use case here is to censor usernames and passwords from command
1121
1184
// Let PHP handle everything else.
1122
1185
return var_export($var, true);
1190
* An improved version of `fnmatch`.
1192
* @param string A glob pattern.
1193
* @param string A path.
1196
function phutil_fnmatch($glob, $path) {
1197
// Modify the glob to allow `**/` to match files in the root directory.
1198
$glob = preg_replace('@(?:(?<!\\\\)\\*){2}/@', '{,*/,**/}', $glob);
1204
for ($i = 0; $i < strlen($glob); $i++) {
1206
$next_char = ($i < strlen($glob) - 1) ? $glob[$i + 1] : null;
1208
$escape = array('$', '(', ')', '+', '.', '^', '|');
1216
$mapping['*'] = $next_char === '*' ? '.*' : '[^/]*';
1217
$mapping['?'] = '[^/]';
1218
$mapping['{'] = '(';
1221
$mapping[','] = '|';
1222
$mapping['}'] = ')';
1226
if (in_array($char, $escape)) {
1227
$regex .= "\\{$char}";
1228
} else if ($replacement = idx($mapping, $char)) {
1229
$regex .= $replacement;
1230
} else if ($char === '\\') {
1234
$escaping = !$escaping;
1240
if ($char === '{' && !$escaping) {
1242
} else if ($char === '}' && $in_curlies && !$escaping) {
1249
if ($in_curlies || $escaping) {
1250
throw new InvalidArgumentException(pht('Invalid glob pattern.'));
1253
$regex = '(\A'.$regex.'\z)';
1254
return (bool)preg_match($regex, $path);