locomotivemtl /
charcoal-config
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | namespace Charcoal\Config; |
||
| 4 | |||
| 5 | use Traversable; |
||
| 6 | use Throwable; |
||
| 7 | use Exception; |
||
| 8 | use LogicException; |
||
| 9 | use InvalidArgumentException; |
||
| 10 | use UnexpectedValueException; |
||
| 11 | |||
| 12 | // From 'symfony/yaml' |
||
| 13 | use Symfony\Component\Yaml\Parser as YamlParser; |
||
| 14 | |||
| 15 | /** |
||
| 16 | * Provides an object with the ability to read file contents. |
||
| 17 | * |
||
| 18 | * Supported file formats: INI, JSON, PHP, YAML*. |
||
| 19 | * |
||
| 20 | * Note: YAML requires the {@link https://packagist.org/packages/symfony/yaml Symfony YAML component}. |
||
| 21 | * |
||
| 22 | * This is a full implementation of {@see FileAwareInterface}. |
||
| 23 | */ |
||
| 24 | trait FileAwareTrait |
||
| 25 | { |
||
| 26 | /** |
||
| 27 | * Loads a configuration file. |
||
| 28 | * |
||
| 29 | * @param string $path A path to a supported file. |
||
| 30 | * @throws InvalidArgumentException If the path is invalid. |
||
| 31 | * @return array An array on success. |
||
| 32 | */ |
||
| 33 | public function loadFile($path) |
||
| 34 | { |
||
| 35 | if (!is_string($path)) { |
||
| 36 | throw new InvalidArgumentException( |
||
| 37 | 'File must be a string' |
||
| 38 | ); |
||
| 39 | } |
||
| 40 | |||
| 41 | if (!file_exists($path)) { |
||
| 42 | throw new InvalidArgumentException( |
||
| 43 | sprintf('File "%s" does not exist', $path) |
||
| 44 | ); |
||
| 45 | } |
||
| 46 | |||
| 47 | $ext = pathinfo($path, PATHINFO_EXTENSION); |
||
| 48 | switch ($ext) { |
||
| 49 | case 'php': |
||
| 50 | return $this->loadPhpFile($path); |
||
| 51 | |||
| 52 | case 'json': |
||
| 53 | return $this->loadJsonFile($path); |
||
| 54 | |||
| 55 | case 'ini': |
||
| 56 | return $this->loadIniFile($path); |
||
| 57 | |||
| 58 | case 'yml': |
||
| 59 | case 'yaml': |
||
| 60 | return $this->loadYamlFile($path); |
||
| 61 | } |
||
| 62 | |||
| 63 | $validConfigExts = [ 'ini', 'json', 'php', 'yml' ]; |
||
| 64 | throw new InvalidArgumentException(sprintf( |
||
| 65 | 'Unsupported file format for "%s"; must be one of "%s"', |
||
| 66 | $path, |
||
| 67 | implode('", "', $validConfigExts) |
||
| 68 | )); |
||
| 69 | } |
||
| 70 | |||
| 71 | /** |
||
| 72 | * Load an INI file as an array. |
||
| 73 | * |
||
| 74 | * @param string $path A path to an INI file. |
||
| 75 | * @throws UnexpectedValueException If the file can not correctly be parsed into an array. |
||
| 76 | * @return array An array on success. |
||
| 77 | */ |
||
| 78 | private function loadIniFile($path) |
||
| 79 | { |
||
| 80 | $data = parse_ini_file($path, true); |
||
| 81 | if ($data === false) { |
||
| 82 | throw new UnexpectedValueException( |
||
| 83 | sprintf('INI file "%s" is empty or invalid', $path) |
||
| 84 | ); |
||
| 85 | } |
||
| 86 | |||
| 87 | return $data; |
||
| 88 | } |
||
| 89 | |||
| 90 | /** |
||
| 91 | * Load a JSON file as an array. |
||
| 92 | * |
||
| 93 | * @param string $path A path to a JSON file. |
||
| 94 | * @throws UnexpectedValueException If the file can not correctly be parsed into an array. |
||
| 95 | * @return array An array on success. |
||
| 96 | * If the file is parsed as any other type, an empty array is returned. |
||
| 97 | */ |
||
| 98 | private function loadJsonFile($path) |
||
| 99 | { |
||
| 100 | $data = null; |
||
| 101 | $json = file_get_contents($path); |
||
| 102 | if ($json) { |
||
| 103 | $data = json_decode($json, true); |
||
| 104 | if (json_last_error() !== JSON_ERROR_NONE) { |
||
| 105 | $error = json_last_error_msg() ?: 'Unknown error'; |
||
| 106 | throw new UnexpectedValueException( |
||
| 107 | sprintf('JSON file "%s" could not be parsed: %s', $path, $error) |
||
| 108 | ); |
||
| 109 | } |
||
| 110 | } |
||
| 111 | |||
| 112 | if (!is_array($data)) { |
||
| 113 | return []; |
||
| 114 | } |
||
| 115 | |||
| 116 | return $data; |
||
| 117 | } |
||
| 118 | |||
| 119 | /** |
||
| 120 | * Load a PHP file, maybe as an array. |
||
| 121 | * |
||
| 122 | * Note: |
||
| 123 | * - The context of $this is bound to the current object. |
||
| 124 | * - Data may be any value; the {@see self::addFile()} method will ignore |
||
| 125 | * anything that isn't an (associative) array. |
||
| 126 | * |
||
| 127 | * @param string $path A path to a PHP file. |
||
| 128 | * @throws UnexpectedValueException If the file can not correctly be parsed. |
||
| 129 | * @return array|Traversable An array or iterable object on success. |
||
| 130 | * If the file is parsed as any other type, an empty array is returned. |
||
| 131 | */ |
||
| 132 | private function loadPhpFile($path) |
||
| 133 | { |
||
| 134 | try { |
||
| 135 | $data = include $path; |
||
| 136 | } catch (Exception $e) { |
||
| 137 | $message = sprintf('PHP file "%s" could not be parsed: %s', $path, $e->getMessage()); |
||
| 138 | throw new UnexpectedValueException($message, 0, $e); |
||
| 139 | } catch (Throwable $e) { |
||
|
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||
| 140 | $message = sprintf('PHP file "%s" could not be parsed: %s', $path, $e->getMessage()); |
||
| 141 | throw new UnexpectedValueException($message, 0, $e); |
||
| 142 | } |
||
| 143 | |||
| 144 | if (is_array($data) || ($data instanceof Traversable)) { |
||
| 145 | return $data; |
||
| 146 | } |
||
| 147 | |||
| 148 | return []; |
||
| 149 | } |
||
| 150 | |||
| 151 | /** |
||
| 152 | * Load a YAML file as an array. |
||
| 153 | * |
||
| 154 | * @param string $path A path to a YAML/YML file. |
||
| 155 | * @throws LogicException If a YAML parser is unavailable. |
||
| 156 | * @throws UnexpectedValueException If the file can not correctly be parsed into an array. |
||
| 157 | * @return array An array on success. |
||
| 158 | * If the file is parsed as any other type, an empty array is returned. |
||
| 159 | */ |
||
| 160 | private function loadYamlFile($path) |
||
| 161 | { |
||
| 162 | if (!class_exists('Symfony\Component\Yaml\Parser')) { |
||
| 163 | throw new LogicException('YAML format requires the Symfony YAML component'); |
||
| 164 | } |
||
| 165 | |||
| 166 | try { |
||
| 167 | $yaml = new YamlParser(); |
||
| 168 | $data = $yaml->parseFile($path); |
||
| 169 | } catch (Exception $e) { |
||
| 170 | $message = sprintf('YAML file "%s" could not be parsed: %s', $path, $e->getMessage()); |
||
| 171 | throw new UnexpectedValueException($message, 0, $e); |
||
| 172 | } |
||
| 173 | |||
| 174 | if (!is_array($data)) { |
||
| 175 | return []; |
||
| 176 | } |
||
| 177 | |||
| 178 | return $data; |
||
| 179 | } |
||
| 180 | } |
||
| 181 |