annotate vendor/psy/psysh/src/Context.php @ 13:5fb285c0d0e3

Update Drupal core to 8.4.7 via Composer. Security update; I *think* we've been lucky to get away with this so far, as we don't support self-registration which seems to be used by the so-called "drupalgeddon 2" attack that 8.4.5 was vulnerable to.
author Chris Cannam
date Mon, 23 Apr 2018 09:33:26 +0100
parents
children c2387f117808
rev   line source
Chris@13 1 <?php
Chris@13 2
Chris@13 3 /*
Chris@13 4 * This file is part of Psy Shell.
Chris@13 5 *
Chris@13 6 * (c) 2012-2018 Justin Hileman
Chris@13 7 *
Chris@13 8 * For the full copyright and license information, please view the LICENSE
Chris@13 9 * file that was distributed with this source code.
Chris@13 10 */
Chris@13 11
Chris@13 12 namespace Psy;
Chris@13 13
Chris@13 14 /**
Chris@13 15 * The Shell execution context.
Chris@13 16 *
Chris@13 17 * This class encapsulates the current variables, most recent return value and
Chris@13 18 * exception, and the current namespace.
Chris@13 19 */
Chris@13 20 class Context
Chris@13 21 {
Chris@13 22 private static $specialNames = ['_', '_e', '__out', '__psysh__', 'this'];
Chris@13 23
Chris@13 24 // Whitelist a very limited number of command-scope magic variable names.
Chris@13 25 // This might be a bad idea, but future me can sort it out.
Chris@13 26 private static $commandScopeNames = [
Chris@13 27 '__function', '__method', '__class', '__namespace', '__file', '__line', '__dir',
Chris@13 28 ];
Chris@13 29
Chris@13 30 private $scopeVariables = [];
Chris@13 31 private $commandScopeVariables = [];
Chris@13 32 private $returnValue;
Chris@13 33 private $lastException;
Chris@13 34 private $lastStdout;
Chris@13 35 private $boundObject;
Chris@13 36
Chris@13 37 /**
Chris@13 38 * Get a context variable.
Chris@13 39 *
Chris@13 40 * @throws InvalidArgumentException If the variable is not found in the current context
Chris@13 41 *
Chris@13 42 * @param string $name
Chris@13 43 *
Chris@13 44 * @return mixed
Chris@13 45 */
Chris@13 46 public function get($name)
Chris@13 47 {
Chris@13 48 switch ($name) {
Chris@13 49 case '_':
Chris@13 50 return $this->returnValue;
Chris@13 51
Chris@13 52 case '_e':
Chris@13 53 if (isset($this->lastException)) {
Chris@13 54 return $this->lastException;
Chris@13 55 }
Chris@13 56 break;
Chris@13 57
Chris@13 58 case '__out':
Chris@13 59 if (isset($this->lastStdout)) {
Chris@13 60 return $this->lastStdout;
Chris@13 61 }
Chris@13 62 break;
Chris@13 63
Chris@13 64 case 'this':
Chris@13 65 if (isset($this->boundObject)) {
Chris@13 66 return $this->boundObject;
Chris@13 67 }
Chris@13 68 break;
Chris@13 69
Chris@13 70 case '__function':
Chris@13 71 case '__method':
Chris@13 72 case '__class':
Chris@13 73 case '__namespace':
Chris@13 74 case '__file':
Chris@13 75 case '__line':
Chris@13 76 case '__dir':
Chris@13 77 if (array_key_exists($name, $this->commandScopeVariables)) {
Chris@13 78 return $this->commandScopeVariables[$name];
Chris@13 79 }
Chris@13 80 break;
Chris@13 81
Chris@13 82 default:
Chris@13 83 if (array_key_exists($name, $this->scopeVariables)) {
Chris@13 84 return $this->scopeVariables[$name];
Chris@13 85 }
Chris@13 86 break;
Chris@13 87 }
Chris@13 88
Chris@13 89 throw new \InvalidArgumentException('Unknown variable: $' . $name);
Chris@13 90 }
Chris@13 91
Chris@13 92 /**
Chris@13 93 * Get all defined variables.
Chris@13 94 *
Chris@13 95 * @return array
Chris@13 96 */
Chris@13 97 public function getAll()
Chris@13 98 {
Chris@13 99 return array_merge($this->scopeVariables, $this->getSpecialVariables());
Chris@13 100 }
Chris@13 101
Chris@13 102 /**
Chris@13 103 * Get all defined magic variables: $_, $_e, $__out, $__class, $__file, etc.
Chris@13 104 *
Chris@13 105 * @return array
Chris@13 106 */
Chris@13 107 public function getSpecialVariables()
Chris@13 108 {
Chris@13 109 $vars = [
Chris@13 110 '_' => $this->returnValue,
Chris@13 111 ];
Chris@13 112
Chris@13 113 if (isset($this->lastException)) {
Chris@13 114 $vars['_e'] = $this->lastException;
Chris@13 115 }
Chris@13 116
Chris@13 117 if (isset($this->lastStdout)) {
Chris@13 118 $vars['__out'] = $this->lastStdout;
Chris@13 119 }
Chris@13 120
Chris@13 121 if (isset($this->boundObject)) {
Chris@13 122 $vars['this'] = $this->boundObject;
Chris@13 123 }
Chris@13 124
Chris@13 125 return array_merge($vars, $this->commandScopeVariables);
Chris@13 126 }
Chris@13 127
Chris@13 128 /**
Chris@13 129 * Set all scope variables.
Chris@13 130 *
Chris@13 131 * This method does *not* set any of the magic variables: $_, $_e, $__out,
Chris@13 132 * $__class, $__file, etc.
Chris@13 133 *
Chris@13 134 * @param array $vars
Chris@13 135 */
Chris@13 136 public function setAll(array $vars)
Chris@13 137 {
Chris@13 138 foreach (self::$specialNames as $key) {
Chris@13 139 unset($vars[$key]);
Chris@13 140 }
Chris@13 141
Chris@13 142 foreach (self::$commandScopeNames as $key) {
Chris@13 143 unset($vars[$key]);
Chris@13 144 }
Chris@13 145
Chris@13 146 $this->scopeVariables = $vars;
Chris@13 147 }
Chris@13 148
Chris@13 149 /**
Chris@13 150 * Set the most recent return value.
Chris@13 151 *
Chris@13 152 * @param mixed $value
Chris@13 153 */
Chris@13 154 public function setReturnValue($value)
Chris@13 155 {
Chris@13 156 $this->returnValue = $value;
Chris@13 157 }
Chris@13 158
Chris@13 159 /**
Chris@13 160 * Get the most recent return value.
Chris@13 161 *
Chris@13 162 * @return mixed
Chris@13 163 */
Chris@13 164 public function getReturnValue()
Chris@13 165 {
Chris@13 166 return $this->returnValue;
Chris@13 167 }
Chris@13 168
Chris@13 169 /**
Chris@13 170 * Set the most recent Exception.
Chris@13 171 *
Chris@13 172 * @param \Exception $e
Chris@13 173 */
Chris@13 174 public function setLastException(\Exception $e)
Chris@13 175 {
Chris@13 176 $this->lastException = $e;
Chris@13 177 }
Chris@13 178
Chris@13 179 /**
Chris@13 180 * Get the most recent Exception.
Chris@13 181 *
Chris@13 182 * @throws \InvalidArgumentException If no Exception has been caught
Chris@13 183 *
Chris@13 184 * @return null|\Exception
Chris@13 185 */
Chris@13 186 public function getLastException()
Chris@13 187 {
Chris@13 188 if (!isset($this->lastException)) {
Chris@13 189 throw new \InvalidArgumentException('No most-recent exception');
Chris@13 190 }
Chris@13 191
Chris@13 192 return $this->lastException;
Chris@13 193 }
Chris@13 194
Chris@13 195 /**
Chris@13 196 * Set the most recent output from evaluated code.
Chris@13 197 *
Chris@13 198 * @param string $lastStdout
Chris@13 199 */
Chris@13 200 public function setLastStdout($lastStdout)
Chris@13 201 {
Chris@13 202 $this->lastStdout = $lastStdout;
Chris@13 203 }
Chris@13 204
Chris@13 205 /**
Chris@13 206 * Get the most recent output from evaluated code.
Chris@13 207 *
Chris@13 208 * @throws \InvalidArgumentException If no output has happened yet
Chris@13 209 *
Chris@13 210 * @return null|string
Chris@13 211 */
Chris@13 212 public function getLastStdout()
Chris@13 213 {
Chris@13 214 if (!isset($this->lastStdout)) {
Chris@13 215 throw new \InvalidArgumentException('No most-recent output');
Chris@13 216 }
Chris@13 217
Chris@13 218 return $this->lastStdout;
Chris@13 219 }
Chris@13 220
Chris@13 221 /**
Chris@13 222 * Set the bound object ($this variable) for the interactive shell.
Chris@13 223 *
Chris@13 224 * @param object|null $boundObject
Chris@13 225 */
Chris@13 226 public function setBoundObject($boundObject)
Chris@13 227 {
Chris@13 228 $this->boundObject = is_object($boundObject) ? $boundObject : null;
Chris@13 229 }
Chris@13 230
Chris@13 231 /**
Chris@13 232 * Get the bound object ($this variable) for the interactive shell.
Chris@13 233 *
Chris@13 234 * @return object|null
Chris@13 235 */
Chris@13 236 public function getBoundObject()
Chris@13 237 {
Chris@13 238 return $this->boundObject;
Chris@13 239 }
Chris@13 240
Chris@13 241 /**
Chris@13 242 * Set command-scope magic variables: $__class, $__file, etc.
Chris@13 243 *
Chris@13 244 * @param array $commandScopeVariables
Chris@13 245 */
Chris@13 246 public function setCommandScopeVariables(array $commandScopeVariables)
Chris@13 247 {
Chris@13 248 $vars = [];
Chris@13 249 foreach ($commandScopeVariables as $key => $value) {
Chris@13 250 // kind of type check
Chris@13 251 if (is_scalar($value) && in_array($key, self::$commandScopeNames)) {
Chris@13 252 $vars[$key] = $value;
Chris@13 253 }
Chris@13 254 }
Chris@13 255
Chris@13 256 $this->commandScopeVariables = $vars;
Chris@13 257 }
Chris@13 258
Chris@13 259 /**
Chris@13 260 * Get command-scope magic variables: $__class, $__file, etc.
Chris@13 261 *
Chris@13 262 * @return array
Chris@13 263 */
Chris@13 264 public function getCommandScopeVariables()
Chris@13 265 {
Chris@13 266 return $this->commandScopeVariables;
Chris@13 267 }
Chris@13 268
Chris@13 269 /**
Chris@13 270 * Get unused command-scope magic variables names: __class, __file, etc.
Chris@13 271 *
Chris@13 272 * This is used by the shell to unset old command-scope variables after a
Chris@13 273 * new batch is set.
Chris@13 274 *
Chris@13 275 * @return array Array of unused variable names
Chris@13 276 */
Chris@13 277 public function getUnusedCommandScopeVariableNames()
Chris@13 278 {
Chris@13 279 return array_diff(self::$commandScopeNames, array_keys($this->commandScopeVariables));
Chris@13 280 }
Chris@13 281
Chris@13 282 /**
Chris@13 283 * Check whether a variable name is a magic variable.
Chris@13 284 *
Chris@13 285 * @param string $name
Chris@13 286 *
Chris@13 287 * @return bool
Chris@13 288 */
Chris@13 289 public static function isSpecialVariableName($name)
Chris@13 290 {
Chris@13 291 return in_array($name, self::$specialNames) || in_array($name, self::$commandScopeNames);
Chris@13 292 }
Chris@13 293 }