Completed
Push — work-fleets ( 5c3a01...351cf4 )
by SuperNova.WS
06:40
created

ContainerAccessors::__set()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 6
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 5
nc 2
nop 2
dl 0
loc 7
rs 9.4285
c 1
b 0
f 0
ccs 6
cts 6
cp 1
crap 2
1
<?php
2
3
use \Common\ContainerMagic;
4
5
/**
6
 * Class ContainerAccessors
7
 *
8
 * Support accessors for properties: getter, setter, unsetter
9
 *
10
 * Below $that - is a shortcut for container object which will be passed to accessor
11
 *
12
 * Getter is a callable like
13
 *    function ($this) {}
14
 *
15
 * Setter is a callable like
16
 *    function ($that, $value)  {}
17
 *
18
 * Unsetter is a callable like
19
 *    function ($that) {}
20
 *
21
 * Use setDirect() and getDirect() methods to access same variable for setter/getter function!
22
 * If setter works with other object properties it needs an unsetter to handle clearProperties() method
23
 *
24
 */
25
class ContainerAccessors extends ContainerMagic {
26
  /**
27
   * Array of accessors - getters/setters/etc
28
   *
29
   * @var callable[][]
30
   */
31
  protected $accessors = array();
32
33
  /**
34
   * @param array $array
35
   */
36 1
  public function setAccessors($array) {
37 1
    $this->accessors = $array;
38 1
  }
39
40
  /**
41
   * Direct access to parent class setter
42
   *
43
   * @param string $name
44
   * @param mixed  $value
45
   *
46
   * @return mixed
47
   */
48 1
  public function setDirect($name, $value) {
49 1
    ContainerMagic::__set($name, $value);
50 1
  }
51
52
  /**
53
   * Direct access to parent class getter
54
   *
55
   * @param string $name
56
   *
57
   * @return mixed
58
   */
59 1
  public function getDirect($name) {
60 1
    return ContainerMagic::__get($name);
61
  }
62
63
  /**
64
   * Direct access to parent class unsetter
65
   *
66
   * @param string $name
67
   */
68 1
  public function unsetDirect($name) {
69 1
    ContainerMagic::__unset($name);
70 1
  }
71
72
  /**
73
   * Assign accessor to a named variable
74
   *
75
   * Different accessors have different signatures - you should look carefully before assigning accessor
76
   *
77
   * @param string   $varName
78
   * @param string   $type - getter/setter/importer/exporter/etc
79
   * @param callable $callable
80
   *
81
   * @throws Exception
82
   */
83 1 View Code Duplication
  public function assignAccessor($varName, $type, $callable) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
84 1
    if (empty($callable)) {
85 1
      return;
86
    }
87
88 1
    if (is_callable($callable)) {
89 1
      $this->accessors[$varName][$type] = $callable;
90 1
    } else {
91 1
      throw new Exception('Error assigning callable in ' . get_called_class() . '! Callable typed [' . $type . '] is not a callable or not accessible in the scope');
92
    }
93 1
  }
94
95
  /**
96
   * Performs $processor operation on property with specified name
97
   *
98
   * @param string     $processor
99
   * @param string     $name
100
   * @param null|mixed $value
101
   *
102
   * @return mixed
103
   */
104 1
  protected function performMagic($processor, $name, $value = null) {
105
    if (
106 1
      !empty($this->accessors[$name][$processor])
107 1
      &&
108 1
      is_callable($this->accessors[$name][$processor])
109 1
    ) {
110 1
      return call_user_func($this->accessors[$name][$processor], $this, $value);
0 ignored issues
show
Security Code Execution introduced by
$this->accessors[$name][$processor] can contain request data and is used in code execution context(s) leading to a potential security vulnerability.

1 path for user data to reach this point

  1. Read from $_POST
    in includes/general.php on line 258
  2. sys_get_param() returns tainted data
    in includes/general.php on line 290
  3. Data is passed through strip_tags(), and Data is passed through trim()
    in vendor/includes/general.php on line 1303
  4. sys_get_param_str_unsafe() returns tainted data, and BuddyParams::$request_text_unsafe is assigned
    in includes/classes/Buddy/BuddyParams.php on line 35
  5. Tainted property BuddyParams::$request_text_unsafe is read
    in includes/classes/Buddy/BuddyModel.php on line 254
  6. $params->request_text_unsafe is passed to ContainerAccessors::__set()
    in includes/classes/Buddy/BuddyModel.php on line -1
  7. ContainerAccessors::$accessors is assigned
    in includes/classes/ContainerAccessors.php on line 118
  8. Tainted property ContainerAccessors::$accessors is read
    in includes/classes/ContainerAccessors.php on line 110

General Strategies to prevent injection

In general, it is advisable to prevent any user-data to reach this point. This can be done by white-listing certain values:

if ( ! in_array($value, array('this-is-allowed', 'and-this-too'), true)) {
    throw new \InvalidArgumentException('This input is not allowed.');
}

For numeric data, we recommend to explicitly cast the data:

$sanitized = (integer) $tainted;
Loading history...
111
    } else {
112 1
      return parent::$processor($name, $value);
113
    }
114
  }
115
116 1
  public function __set($name, $value) {
117 1
    if (is_callable($value)) {
118 1
      $this->accessors[$name][P_CONTAINER_GET] = $value;
119 1
    } else {
120 1
      $this->performMagic(P_CONTAINER_SET, $name, $value);
121
    }
122 1
  }
123
124 1
  public function __get($name) {
125 1
    return $this->performMagic(P_CONTAINER_GET, $name, null);
126
  }
127
128 1
  public function __unset($name) {
129 1
    $this->performMagic(P_CONTAINER_UNSET, $name, null);
130 1
  }
131
132 1
  public function __isset($name) {
133
    // TODO - or here already can isset($this->name) ????
0 ignored issues
show
Unused Code Comprehensibility introduced by
42% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
134 1
    $value = $this->$name;
135
136 1
    return isset($value);
137
  }
138
139
}
140