Issues (17)

Security Analysis    no request data  

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

lib/Election.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/*
3
    Condorcet PHP - Election manager and results calculator.
4
    Designed for the Condorcet method. Integrating a large number of algorithms extending Condorcet. Expandable for all types of voting systems.
5
6
    By Julien Boudry and contributors - MIT LICENSE (Please read LICENSE.txt)
7
    https://github.com/julien-boudry/Condorcet
8
*/
9
declare(strict_types=1);
10
11
namespace CondorcetPHP\Condorcet;
12
13
use CondorcetPHP\Condorcet\DataManager\VotesManager;
14
use CondorcetPHP\Condorcet\DataManager\DataHandlerDrivers\DataHandlerDriverInterface;
15
use CondorcetPHP\Condorcet\ElectionProcess\{CandidatesProcess, ResultsProcess, VotesProcess};
16
use CondorcetPHP\Condorcet\Throwable\CondorcetException;
17
use CondorcetPHP\Condorcet\Timer\Manager as Timer_Manager;
18
19
// Base Condorcet class
20
class Election
21
{
22
23
/////////// PROPERTIES ///////////
24
25
    public const MAX_LENGTH_CANDIDATE_ID = 30; // Max length for candidate identifiant string
26
27
    protected static $_maxParseIteration = null;
28
    protected static $_maxVoteNumber = null;
29
    protected static $_checksumMode = false;
30
31
/////////// STATICS METHODS ///////////
32
33
    // Change max parse iteration
34 3
    public static function setMaxParseIteration (?int $maxParseIterations) : ?int
35
    {
36 3
        self::$_maxParseIteration = $maxParseIterations;
37 3
        return self::$_maxParseIteration;
38
    }
39
40
    // Change max vote number
41 1
    public static function setMaxVoteNumber (?int $maxVotesNumber) : ?int
42
    {
43 1
        self::$_maxVoteNumber = $maxVotesNumber;
44 1
        return self::$_maxVoteNumber;
45
    }
46
47
48
/////////// CONSTRUCTOR ///////////
49
50
    use CondorcetVersion;
51
52
    // Mechanics
53
    protected $_State = 1; // 1 = Add Candidates / 2 = Voting / 3 = Some result have been computing
54
    protected $_timer;
55
56
    // Params
57
    protected $_ImplicitRanking = true;
58
    protected $_VoteWeightRule = false;
59
    protected $_Constraints = [];
60
61
        //////
62
63 158
    public function __construct ()
64
    {
65 158
        $this->_Candidates = [];
66 158
        $this->_Votes = new VotesManager ($this);
67 158
        $this->_timer = new Timer_Manager;
68 158
    }
69
70
    public function __destruct ()
71
    {
72
        $this->destroyAllLink();
73
    }
74
75 2
    public function __sleep () : array
76
    {
77
        // Don't include others data
78
        $include = [
79 2
            '_Candidates',
80
            '_Votes',
81
82
            '_AutomaticNewCandidateName',
83
            '_State',
84
            '_objectVersion',
85
86
            '_ImplicitRanking',
87
            '_VoteWeightRule',
88
            '_Constraints',
89
90
            '_Pairwise',
91
            '_Calculator',
92
        ];
93
94 2
        !self::$_checksumMode && array_push($include, '_timer');
95
96 2
        return $include;
97
    }
98
99 2
    public function __wakeup ()
100
    {
101 2
        if ( version_compare($this->getObjectVersion(true),Condorcet::getVersion(true),'!=') ) :
102
            throw new CondorcetException(11, 'Your object version is '.$this->getObjectVersion().' but the class engine version is '.Condorcet::getVersion());
103
        endif;
104 2
    }
105
106 1
    public function __clone ()
107
    {
108 1
        $this->_Votes = clone $this->_Votes;
109 1
        $this->_Votes->setElection($this);      
110 1
        $this->registerAllLinks();
111
112 1
        $this->_timer = clone $this->_timer;
113
114 1
        if ($this->_Pairwise !== null) :
115 1
            $this->_Pairwise = clone $this->_Pairwise;
116 1
            $this->_Pairwise->setElection($this);
117
        endif;
118 1
    }
119
120
121
/////////// TIMER & CHECKSUM ///////////
122
123 2
    public function getGlobalTimer () : float {
124 2
        return $this->_timer->getGlobalTimer();
125
    }
126
127 2
    public function getLastTimer () : float {
128 2
        return $this->_timer->getLastTimer();
129
    }
130
131 95
    public function getTimerManager () : Timer_Manager {
132 95
        return $this->_timer;
133
    }
134
135 1
    public function getChecksum () : string
136
    {
137 1
        self::$_checksumMode = true;
138
139 1
        $r = hash_init('sha256');
140
141 1
        foreach ($this->_Candidates as $value) :
142 1
            hash_update($r, (string) $value);
143
        endforeach;
144
145 1
        foreach ($this->_Votes as $value) :
146 1
            hash_update($r, (string) $value);
147
        endforeach;
148
149 1
        $this->_Pairwise !== null
150 1
            && hash_update($r,serialize($this->_Pairwise->getExplicitPairwise()));
151
152 1
        hash_update($r, $this->getObjectVersion(true));
153
154 1
        self::$_checksumMode = false;
155
156 1
        return hash_final($r);
157
    }
158
159
160
/////////// LINKS REGULATION ///////////
161
162 1
    protected function registerAllLinks () : void
163
    {
164 1
        foreach ($this->_Candidates as $value) :
165 1
            $value->registerLink($this);
166
        endforeach;
167
168 1
        if ($this->_State > 1) :
169 1
            foreach ($this->_Votes as $value) :
170 1
                $value->registerLink($this);
171
            endforeach;
172
        endif;
173 1
    }
174
175
    protected function destroyAllLink () : void
176
    {
177
        foreach ($this->_Candidates as $value) :
178
            $value->destroyLink($this);
179
        endforeach;
180
181
        if ($this->_State > 1) :
182
            foreach ($this->_Votes as $value) :
183
                $value->destroyLink($this);
184
            endforeach;
185
        endif;
186
    }
187
188
189
  /////////// IMPLICIT RANKING & VOTE WEIGHT ///////////
190
191 102
    public function getImplicitRankingRule () : bool
192
    {
193 102
        return $this->_ImplicitRanking;
194
    }
195
196 6
    public function setImplicitRanking (bool $rule = true) : bool
197
    {
198 6
        $this->_ImplicitRanking = $rule;
199 6
        $this->cleanupCompute();
200 6
        return $this->getImplicitRankingRule();
201
    }
202
203 98
    public function isVoteWeightAllowed () : bool
204
    {
205 98
        return $this->_VoteWeightRule;
206
    }
207
208 4
    public function allowVoteWeight (bool $rule = true) : bool
209
    {
210 4
        $this->_VoteWeightRule = $rule;
211 4
        $this->cleanupCompute();
212 4
        return $this->isVoteWeightAllowed();
213
    }
214
215
216
    /////////// VOTE CONSTRAINT ///////////
217
218 4
    public function addConstraint (string $constraintClass) : bool
219
    {
220 4
        if ( !class_exists($constraintClass) ) :
221 1
            throw new CondorcetException(27);
222 3
        elseif ( !is_subclass_of($constraintClass, VoteConstraint::class) ) :
0 ignored issues
show
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \CondorcetPHP\Condorcet\VoteConstraint::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
223 1
            throw new CondorcetException(28);
224 2
        elseif (in_array($constraintClass,$this->getConstraints(), true)) :
225 1
            throw new CondorcetException(29);
226
        endif;
227
228 2
        if ( $this->_State > 2) :
229 1
            $this->cleanupCompute();;
230
        endif;
231
232 2
        $this->_Constraints[] = $constraintClass;
233
234 2
        return true;
235
    }
236
237 2
    public function getConstraints () : array
238
    {
239 2
        return $this->_Constraints;
240
    }
241
242 2
    public function clearConstraints () : bool
243
    {
244 2
        $this->_Constraints = [];
245
246 2
        if ( $this->_State > 2) :
247 1
            $this->cleanupCompute();;
248
        endif;
249
250 2
        return true;
251
    }
252
253 95
    public function testIfVoteIsValidUnderElectionConstraints (Vote $vote) : bool
254
    {
255 95
        foreach ($this->_Constraints as $oneConstraint) :
256 1
            if ($oneConstraint::isVoteAllow($this,$vote) === false) :
257 1
                return false;
258
            endif;
259
        endforeach;
260
261 95
        return true;
262
    }
263
264
265
/////////// LARGE ELECTION MODE ///////////
266
267 7
    public function setExternalDataHandler (DataHandlerDriverInterface $driver) : bool
268
    {
269 7
        if (!$this->_Votes->isUsingHandler()) :
270 7
            $this->_Votes->importHandler($driver);
271 7
            return true;
272
        else :
273 1
            throw new CondorcetException(24);
274
        endif;
275
    }
276
277 1
    public function removeExternalDataHandler () : bool
278
    {
279 1
        if ($this->_Votes->isUsingHandler()) :
280 1
            $this->_Votes->closeHandler();
281 1
            return true;
282
        else :
283 1
            throw new CondorcetException(23);
284
        endif;
285
    }
286
287
288
/////////// STATE ///////////
289
290 131
    public function getState () : int
291
    {
292 131
        return $this->_State;
293
    }
294
295
    // Close the candidate config, be ready for voting (optional)
296 131
    public function setStateToVote () : bool
297
    {
298 131
        if ( $this->_State === 1 ) :
299 131
                if (empty($this->_Candidates)) :
300 1
                    throw new CondorcetException(20);
301
                endif;
302
303 131
                $this->_State = 2;
304
305
        // If voting continues after a first set of results
306 112
        elseif ( $this->_State > 2 ) :
307
                $this->cleanupCompute();
308
        endif;
309
310 131
        return true;
311
    }
312
313
    // Prepare to compute results & caching system
314 96
    protected function prepareResult () : bool
315
    {
316 96
        if ($this->_State > 2) :
317 89
            return false;
318 96
        elseif ($this->_State === 2) :
319 95
            $this->cleanupCompute();
320
321
            // Do Pairewise
322 95
            $this->makePairwise();
323
324
            // Change state to result
325 95
            $this->_State = 3;
326
327
            // Return
328 95
            return true;
329
        else :
330 1
            throw new CondorcetException(6);
331
        endif;
332
    }
333
334
335
/////////// CANDIDATES ///////////
336
337
    use CandidatesProcess;
338
339
340
/////////// VOTING ///////////
341
342
    use VotesProcess;
343
344
345
/////////// RESULTS ///////////
346
347
    use ResultsProcess;
348
}
349