pinepain /
js-sandbox
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 declare(strict_types=1); |
||
| 2 | |||
| 3 | /* |
||
| 4 | * This file is part of the pinepain/js-sandbox PHP library. |
||
| 5 | * |
||
| 6 | * Copyright (c) 2016-2017 Bogdan Padalko <[email protected]> |
||
| 7 | * |
||
| 8 | * Licensed under the MIT license: http://opensource.org/licenses/MIT |
||
| 9 | * |
||
| 10 | * For the full copyright and license information, please view the |
||
| 11 | * LICENSE file that was distributed with this source or visit |
||
| 12 | * http://opensource.org/licenses/MIT |
||
| 13 | */ |
||
| 14 | |||
| 15 | |||
| 16 | namespace Pinepain\JsSandbox\Wrappers\ObjectComponents; |
||
| 17 | |||
| 18 | |||
| 19 | use Pinepain\JsSandbox\Exceptions\NativeException; |
||
| 20 | use Pinepain\JsSandbox\Extractors\ExtractorException; |
||
| 21 | use Pinepain\JsSandbox\Extractors\ExtractorInterface; |
||
| 22 | use Pinepain\JsSandbox\Specs\BindingSpecInterface; |
||
| 23 | use Pinepain\JsSandbox\Specs\FunctionSpecInterface; |
||
| 24 | use Pinepain\JsSandbox\Wrappers\CallbackGuards\CallbackGuardInterface; |
||
| 25 | use Pinepain\JsSandbox\Wrappers\Runtime\RuntimeFunction; |
||
| 26 | use Pinepain\JsSandbox\Wrappers\Runtime\RuntimeObject; |
||
| 27 | use V8\FunctionObject; |
||
| 28 | use V8\NamedPropertyHandlerConfiguration; |
||
| 29 | use V8\NameValue; |
||
| 30 | use V8\PropertyAttribute; |
||
| 31 | use V8\PropertyCallbackInfo; |
||
| 32 | use V8\Value; |
||
| 33 | |||
| 34 | |||
| 35 | class PropertiesHandler implements PropertiesHandlerInterface |
||
| 36 | { |
||
| 37 | /** |
||
| 38 | * @var CallbackGuardInterface |
||
| 39 | */ |
||
| 40 | private $guard; |
||
| 41 | /** |
||
| 42 | * @var ExtractorInterface |
||
| 43 | */ |
||
| 44 | private $extractor; |
||
| 45 | |||
| 46 | public function __construct(CallbackGuardInterface $guard, ExtractorInterface $extractor) |
||
| 47 | { |
||
| 48 | $this->guard = $guard; |
||
| 49 | $this->extractor = $extractor; |
||
| 50 | } |
||
| 51 | |||
| 52 | public function getter(RuntimeObject $bridge, NameValue $name, PropertyCallbackInfo $args): void |
||
| 53 | { |
||
| 54 | $js_object = $args->this(); |
||
| 55 | |||
| 56 | $spec = $bridge->getSpec(); |
||
| 57 | $prop_name = $name->value(); |
||
| 58 | |||
| 59 | if (!$spec->hasProperty($prop_name)) { |
||
| 60 | return; |
||
| 61 | } |
||
| 62 | |||
| 63 | $property_spec = $spec->getProperty($prop_name); |
||
| 64 | |||
| 65 | if ($property_spec instanceof BindingSpecInterface) { |
||
| 66 | $prop_name = $property_spec->getName(); |
||
| 67 | $property_spec = $property_spec->getSpec(); |
||
| 68 | } |
||
| 69 | |||
| 70 | if ($property_spec instanceof FunctionSpecInterface) { |
||
| 71 | $js_function = $bridge->getMethod($prop_name); |
||
| 72 | if (!$js_function) { |
||
| 73 | /** @var callable $callback */ |
||
| 74 | $callback = [$bridge->getObject(), $prop_name]; |
||
| 75 | $func = new RuntimeFunction($prop_name, $callback, $property_spec); |
||
| 76 | /** @var FunctionObject $js_function */ |
||
| 77 | $js_function = $bridge->getWrapper()->wrap($args->getIsolate(), $args->getContext(), $func); |
||
| 78 | |||
| 79 | $bridge->storeMethod($prop_name, $js_function, $js_object); |
||
| 80 | // TODO: is TODO below is still relevant? |
||
| 81 | // TODO: store function object in object map |
||
| 82 | } |
||
| 83 | $ret = $js_function; |
||
| 84 | } else { |
||
| 85 | // NOTE: we don't handle static properties at this time |
||
| 86 | |||
| 87 | if ($getter = $property_spec->getGetterName()) { |
||
| 88 | $prop_value = $bridge->getObject()->$getter(); |
||
| 89 | } else { |
||
| 90 | $prop_value = $bridge->getObject()->$prop_name; |
||
| 91 | } |
||
| 92 | |||
| 93 | $ret = $bridge->getWrapper()->wrap($args->getIsolate(), $args->getContext(), $prop_value); |
||
| 94 | } |
||
| 95 | |||
| 96 | $args->getReturnValue()->set($ret); |
||
| 97 | } |
||
| 98 | |||
| 99 | public function setter(RuntimeObject $bridge, NameValue $name, Value $value, PropertyCallbackInfo $args): void |
||
| 100 | { |
||
| 101 | $spec = $bridge->getSpec(); |
||
| 102 | $prop_name = $name->value(); |
||
| 103 | |||
| 104 | if (!$spec->hasProperty($prop_name)) { |
||
| 105 | return; |
||
| 106 | } |
||
| 107 | |||
| 108 | $property_spec = $spec->getProperty($prop_name); |
||
| 109 | |||
| 110 | if ($property_spec instanceof BindingSpecInterface) { |
||
| 111 | $prop_name = $property_spec->getName(); |
||
| 112 | $property_spec = $property_spec->getSpec(); |
||
| 113 | } |
||
| 114 | |||
| 115 | if ($property_spec instanceof FunctionSpecInterface || $property_spec->isReadonly()) { |
||
| 116 | return; |
||
| 117 | } |
||
| 118 | |||
| 119 | try { |
||
| 120 | $definition = $property_spec->getExtractorDefinition(); |
||
| 121 | assert(null !== $definition); |
||
| 122 | |||
| 123 | $prop_value = $this->extractor->extract($args->getContext(), $value, $definition); |
||
| 124 | } catch (ExtractorException $e) { |
||
| 125 | throw new NativeException("Failed to set property value: {$e->getMessage()}"); |
||
| 126 | } |
||
| 127 | |||
| 128 | // NOTE: we don't handle static props here |
||
| 129 | |||
| 130 | if ($setter = $property_spec->getSetterName()) { |
||
| 131 | $bridge->getObject()->$setter($prop_value); |
||
| 132 | |||
| 133 | return; |
||
| 134 | } |
||
| 135 | |||
| 136 | $bridge->getObject()->$prop_name = $prop_value; |
||
| 137 | } |
||
| 138 | |||
| 139 | public function query(RuntimeObject $bridge, NameValue $name, PropertyCallbackInfo $args): void |
||
| 140 | { |
||
| 141 | $spec = $bridge->getSpec(); |
||
| 142 | $prop_name = $name->value(); |
||
| 143 | |||
| 144 | if (!$spec->hasProperty($prop_name)) { |
||
| 145 | return; |
||
| 146 | } |
||
| 147 | |||
| 148 | $property_spec = $spec->getProperty($prop_name); |
||
| 149 | |||
| 150 | if ($property_spec instanceof BindingSpecInterface) { |
||
| 151 | $prop_name = $property_spec->getName(); |
||
|
0 ignored issues
–
show
|
|||
| 152 | $property_spec = $property_spec->getSpec(); |
||
| 153 | } |
||
| 154 | |||
| 155 | // Functions should be always read-only |
||
| 156 | if ($property_spec instanceof FunctionSpecInterface || $property_spec->isReadonly()) { |
||
| 157 | $args->getReturnValue()->setInteger(PropertyAttribute::READ_ONLY | PropertyAttribute::DONT_DELETE); |
||
| 158 | } |
||
| 159 | |||
| 160 | $args->getReturnValue()->setInteger(PropertyAttribute::DONT_DELETE); |
||
| 161 | } |
||
| 162 | |||
| 163 | public function deleter(RuntimeObject $bridge, NameValue $name, PropertyCallbackInfo $args): void |
||
| 164 | { |
||
| 165 | $spec = $bridge->getSpec(); |
||
| 166 | $prop_name = $name->value(); |
||
| 167 | |||
| 168 | if (!$spec->hasProperty($prop_name)) { |
||
| 169 | return; |
||
| 170 | } |
||
| 171 | |||
| 172 | $args->getReturnValue()->setBool(false); // We don't allow to delete any property from js |
||
| 173 | } |
||
| 174 | |||
| 175 | public function enumerator(RuntimeObject $bridge, PropertyCallbackInfo $args): void |
||
| 176 | { |
||
| 177 | $spec = $bridge->getSpec(); |
||
| 178 | |||
| 179 | $names = array_keys($spec->getProperties()); |
||
| 180 | |||
| 181 | $args->getReturnValue()->set($bridge->getWrapper()->wrap($args->getIsolate(), $args->getContext(), $names)); |
||
| 182 | } |
||
| 183 | |||
| 184 | public function createGetter(RuntimeObject $bridge): callable |
||
| 185 | { |
||
| 186 | return $this->guard->guard(function (NameValue $name, PropertyCallbackInfo $args) use ($bridge) { |
||
| 187 | $this->getter($bridge, $name, $args); |
||
| 188 | }); |
||
| 189 | } |
||
| 190 | |||
| 191 | public function createSetter(RuntimeObject $bridge): callable |
||
| 192 | { |
||
| 193 | return $this->guard->guard(function (NameValue $name, Value $value, PropertyCallbackInfo $args) use ($bridge) { |
||
| 194 | $this->setter($bridge, $name, $value, $args); |
||
| 195 | }); |
||
| 196 | } |
||
| 197 | |||
| 198 | public function createQuery(RuntimeObject $bridge): callable |
||
| 199 | { |
||
| 200 | return $this->guard->guard(function (NameValue $name, PropertyCallbackInfo $args) use ($bridge) { |
||
| 201 | $this->query($bridge, $name, $args); |
||
| 202 | }); |
||
| 203 | } |
||
| 204 | |||
| 205 | public function createDeleter(RuntimeObject $bridge): callable |
||
| 206 | { |
||
| 207 | return $this->guard->guard(function (NameValue $name, PropertyCallbackInfo $args) use ($bridge) { |
||
| 208 | $this->deleter($bridge, $name, $args); |
||
| 209 | }); |
||
| 210 | } |
||
| 211 | |||
| 212 | public function createEnumerator(RuntimeObject $bridge): callable |
||
| 213 | { |
||
| 214 | return $this->guard->guard(function (PropertyCallbackInfo $args) use ($bridge) { |
||
| 215 | $this->enumerator($bridge, $args); |
||
| 216 | }); |
||
| 217 | } |
||
| 218 | |||
| 219 | public function createConfiguration(RuntimeObject $bridge): NamedPropertyHandlerConfiguration |
||
| 220 | { |
||
| 221 | return new NamedPropertyHandlerConfiguration( |
||
| 222 | $this->createGetter($bridge), |
||
| 223 | $this->createSetter($bridge), |
||
| 224 | $this->createQuery($bridge), |
||
| 225 | $this->createDeleter($bridge), |
||
| 226 | $this->createEnumerator($bridge) |
||
| 227 | ); |
||
| 228 | } |
||
| 229 | } |
||
| 230 |
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.
Both the
$myVarassignment in line 1 and the$higherassignment in line 2 are dead. The first because$myVaris never used and the second because$higheris always overwritten for every possible time line.