Skip to content

Commit f401c01

Browse files
author
Jonathon Hill
committed
Level 9 static analysis
1 parent c964e02 commit f401c01

21 files changed

+268
-61
lines changed

phpstan.neon

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
parameters:
2-
level: 7
2+
level: 9
33
paths:
44
- src
55
- tests

src/Factory.php

+71-10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use InvalidArgumentException;
88
use Psr\SimpleCache\CacheInterface;
9+
use SessionHandlerInterface;
910

1011
class Factory
1112
{
@@ -17,71 +18,131 @@ public function configFromArray(array $settings): Config
1718
$config = new Config();
1819

1920
if (isset($settings['save_path'])) {
21+
if (!is_string($settings['save_path'])) {
22+
throw new InvalidArgumentException('save_path must be a string');
23+
}
2024
$config->setSavePath($settings['save_path']);
2125
}
2226

2327
if (isset($settings['save_handler'])) {
28+
if (! ($settings['save_handler'] instanceof SessionHandlerInterface)) {
29+
throw new InvalidArgumentException('save_handler must implement SessionHandlerInterface');
30+
}
2431
$config->setSaveHandler($settings['save_handler']);
2532
}
2633

2734
if (isset($settings['serialize_handler'])) {
35+
if (!is_string($settings['serialize_handler']) && !is_null($settings['serialize_handler'])) {
36+
throw new InvalidArgumentException('serialize_handler must be a string or null');
37+
}
2838
$config->setSerializeHandler(
2939
Serializers\Factory::auto($settings['serialize_handler'])
3040
);
3141
}
3242

3343
if (isset($settings['name'])) {
44+
if (!is_string($settings['name'])) {
45+
throw new InvalidArgumentException('name must be a string');
46+
}
3447
$config->setName($settings['name']);
3548
}
3649

3750
if (isset($settings['cookie_lifetime'])) {
38-
$config->setCookieLifetime((int) $settings['cookie_lifetime']);
51+
if (!is_int($settings['cookie_lifetime'])) {
52+
throw new InvalidArgumentException('cookie_lifetime must be an integer');
53+
}
54+
$config->setCookieLifetime($settings['cookie_lifetime']);
3955
}
56+
4057
if (isset($settings['cookie_path'])) {
58+
if (!is_string($settings['cookie_path'])) {
59+
throw new InvalidArgumentException('cookie_path must be a string');
60+
}
4161
$config->setCookiePath($settings['cookie_path']);
4262
}
63+
4364
if (isset($settings['cookie_domain'])) {
65+
if (!is_string($settings['cookie_domain'])) {
66+
throw new InvalidArgumentException('cookie_domain must be a string');
67+
}
4468
$config->setCookieDomain($settings['cookie_domain']);
4569
}
70+
4671
if (isset($settings['cookie_secure'])) {
47-
$config->setCookieSecure((bool) $settings['cookie_secure']);
72+
if (!is_bool($settings['cookie_secure'])) {
73+
throw new InvalidArgumentException('cookie_secure must be a boolean');
74+
}
75+
$config->setCookieSecure($settings['cookie_secure']);
4876
}
77+
4978
if (isset($settings['cookie_httponly'])) {
50-
$config->setCookieHttpOnly((bool) $settings['cookie_httponly']);
79+
if (!is_bool($settings['cookie_httponly'])) {
80+
throw new InvalidArgumentException('cookie_httponly must be a boolean');
81+
}
82+
$config->setCookieHttpOnly($settings['cookie_httponly']);
5183
}
84+
5285
if (isset($settings['cookie_samesite'])) {
86+
if (!is_string($settings['cookie_samesite'])) {
87+
throw new InvalidArgumentException('cookie_samesite must be a string');
88+
}
5389
$config->setCookieSameSite($settings['cookie_samesite']);
5490
}
5591

5692
if (isset($settings['cache_limiter'])) {
93+
if (!is_string($settings['cache_limiter'])) {
94+
throw new InvalidArgumentException('cache_limiter must be a string');
95+
}
5796
$config->setCacheLimiter($settings['cache_limiter']);
5897
}
98+
5999
if (isset($settings['cache_expire'])) {
60-
$config->setCacheExpire((int) $settings['cache_expire']);
100+
if (!is_int($settings['cache_expire'])) {
101+
throw new InvalidArgumentException('cache_expire must be an integer');
102+
}
103+
$config->setCacheExpire($settings['cache_expire']);
61104
}
62105

63106
if (isset($settings['gc_probability'])) {
64-
$config->setGcProbability((int) $settings['gc_probability']);
107+
if (!is_int($settings['gc_probability'])) {
108+
throw new InvalidArgumentException('gc_probability must be an integer');
109+
}
110+
$config->setGcProbability($settings['gc_probability']);
65111
}
66112

67113
if (isset($settings['gc_divisor'])) {
68-
$config->setGcDivisor((int) $settings['gc_divisor']);
114+
if (!is_int($settings['gc_divisor'])) {
115+
throw new InvalidArgumentException('gc_divisor must be an integer');
116+
}
117+
$config->setGcDivisor($settings['gc_divisor']);
69118
}
70119

71120
if (isset($settings['gc_maxlifetime'])) {
72-
$config->setGcMaxLifetime((int) $settings['gc_maxlifetime']);
121+
if (!is_int($settings['gc_maxlifetime'])) {
122+
throw new InvalidArgumentException('gc_maxlifetime must be an integer');
123+
}
124+
$config->setGcMaxLifetime($settings['gc_maxlifetime']);
73125
}
74126

75127
if (isset($settings['sid_length'])) {
76-
$config->setSidLength((int) $settings['sid_length']);
128+
if (!is_int($settings['sid_length'])) {
129+
throw new InvalidArgumentException('sid_length must be an integer');
130+
}
131+
$config->setSidLength($settings['sid_length']);
77132
}
78133

79134
if (isset($settings['sid_bits_per_character'])) {
80-
$config->setSidBitsPerCharacter((int) $settings['sid_bits_per_character']);
135+
if (!is_int($settings['sid_bits_per_character'])) {
136+
throw new InvalidArgumentException('sid_bits_per_character must be an integer');
137+
}
138+
$config->setSidBitsPerCharacter($settings['sid_bits_per_character']);
81139
}
82140

83141
if (isset($settings['lazy_write'])) {
84-
$config->setLazyWrite((bool) $settings['lazy_write']);
142+
if (!is_bool($settings['lazy_write'])) {
143+
throw new InvalidArgumentException('lazy_write must be a boolean');
144+
}
145+
$config->setLazyWrite($settings['lazy_write']);
85146
}
86147

87148
return $config;

src/Handlers/ArrayHandler.php

+7-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use SessionHandlerInterface;
1313
use SessionIdInterface;
1414
use SessionUpdateTimestampHandlerInterface;
15+
use TypeError;
1516

1617
/**
1718
* Array session store. This session store does not actually persist data and is meant only for testing.
@@ -65,7 +66,11 @@ public function read($id)
6566
return false;
6667
}
6768

68-
return $this->store[$id]['data'];
69+
$value = $this->store[$id]['data'];
70+
if (is_string($value) || $value === false) {
71+
return $value;
72+
}
73+
throw new TypeError('Expected $value to be a string or false');
6974
}
7075

7176
/**
@@ -103,7 +108,7 @@ public function write($id, $data): bool
103108
/**
104109
* @param float $token
105110
* @param string $id
106-
* @param mixed $data
111+
* @param string $data
107112
*/
108113
public function write_cas($token, $id, $data): bool
109114
{

src/Handlers/Psr16Handler.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use SessionHandlerInterface;
1313
use SessionIdInterface;
1414
use SessionUpdateTimestampHandlerInterface;
15+
use TypeError;
1516

1617
/**
1718
* PSR-16 session store.
@@ -56,7 +57,11 @@ public function read($id)
5657
return false;
5758
}
5859

59-
return $this->store->get($id);
60+
$value = $this->store->get($id);
61+
if (is_string($value) || $value === false) {
62+
return $value;
63+
}
64+
throw new TypeError('Expected $value to be a string or false');
6065
}
6166

6267
public function write($id, $data): bool

src/Handlers/RedisHandler.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public function open($path, $name): bool
5454

5555
$port = isset($config['port']) && !is_null($config['port'])
5656
? (int) $config['port']
57-
: null;
57+
: 6379;
5858

5959
if (!$redis->connect($config['host'], $port)) {
6060
unset($redis);
@@ -82,7 +82,7 @@ public function open($path, $name): bool
8282

8383
public function close(): bool
8484
{
85-
$this->store = null;
85+
unset($this->store);
8686

8787
if (!isset($this->redis)) {
8888
return false;

src/Handlers/ScrapbookHandler.php

+8-3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use SessionHandlerInterface;
1313
use SessionIdInterface;
1414
use SessionUpdateTimestampHandlerInterface;
15+
use TypeError;
1516

1617
/**
1718
* KeyValueStore session store (matthiasmullie/scrapbook).
@@ -31,7 +32,7 @@ class ScrapbookHandler implements
3132

3233
protected KeyValueStore $parentStore;
3334

34-
protected ?KeyValueStore $store;
35+
protected KeyValueStore $store;
3536

3637
protected bool $disableCollections;
3738

@@ -69,12 +70,16 @@ public function close(): bool
6970
*/
7071
public function read($id)
7172
{
72-
return $this->store->get($id);
73+
$value = $this->store->get($id);
74+
if (is_string($value) || $value === false) {
75+
return $value;
76+
}
77+
throw new TypeError('Expected $value to be a string or false');
7378
}
7479

7580
/**
7681
* @param string $id
77-
* @return array{0: mixed, 1: string}|false
82+
* @return array{mixed, string}|false
7883
*/
7984
public function read_cas($id)
8085
{

src/Handlers/SessionCasHandlerInterface.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ interface SessionCasHandlerInterface
1010
{
1111
/**
1212
* @param string $id
13-
* @return mixed
13+
* @return array{mixed, string|int|float}
1414
*/
1515
public function read_cas($id);
1616

src/Manager.php

+36-9
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,14 @@ public function abort(): bool
4848
if (!isset($this->currentSession)) {
4949
return false;
5050
}
51-
5251
$this->currentSession->close();
53-
return !!$this->config->getSaveHandler()->close();
52+
53+
$handler = $this->config->getSaveHandler();
54+
if (!$handler) {
55+
return false;
56+
}
57+
58+
return $handler->close();
5459
}
5560

5661
/**
@@ -63,6 +68,10 @@ public function commit(): bool
6368
}
6469

6570
$handler = $this->config->getSaveHandler();
71+
if (!$handler) {
72+
return false;
73+
}
74+
6675
$id = $this->currentSession->getId();
6776
$contents = $this->encode();
6877

@@ -128,9 +137,11 @@ public function decode(string $data): bool
128137
*/
129138
public function destroy(): bool
130139
{
131-
return !!$this->config
132-
->getSaveHandler()
133-
->destroy($this->currentSession->getId());
140+
$handler = $this->config->getSaveHandler();
141+
if ($handler) {
142+
return $handler->destroy($this->currentSession->getId());
143+
}
144+
return false;
134145
}
135146

136147
/**
@@ -155,9 +166,11 @@ public function encode()
155166
*/
156167
public function gc()
157168
{
158-
return $this->config
159-
->getSaveHandler()
160-
->gc($this->config->getGcMaxLifetime());
169+
$handler = $this->config->getSaveHandler();
170+
if ($handler) {
171+
return $handler->gc($this->config->getGcMaxLifetime());
172+
}
173+
return false;
161174
}
162175

163176
/**
@@ -210,6 +223,10 @@ public function regenerate_id(bool $delete_old_session = false): bool
210223
$oldId = $this->currentSession->getId();
211224
$handler = $this->config->getSaveHandler();
212225

226+
if (!$handler) {
227+
return false;
228+
}
229+
213230
$newId = $this->create_id();
214231
$contents = $this->encode();
215232

@@ -250,6 +267,9 @@ public function reset(): bool
250267
}
251268

252269
$handler = $this->config->getSaveHandler();
270+
if (!$handler) {
271+
return false;
272+
}
253273

254274
if ($handler instanceof Handlers\SessionCasHandlerInterface) {
255275
list($contents, $token) = $handler->read_cas($this->currentSession->getId());
@@ -313,9 +333,12 @@ public function set_save_handler(
313333
public function start(): bool
314334
{
315335
$handler = $this->config->getSaveHandler();
336+
if (!$handler) {
337+
return false;
338+
}
316339

317340
$isOpen = $handler->open(
318-
$this->config->getSavePath(),
341+
$this->config->getSavePath() ?? '',
319342
$this->config->getName()
320343
);
321344

@@ -436,6 +459,10 @@ public function write_close(): bool
436459
}
437460

438461
$handler = $this->config->getSaveHandler();
462+
if (!$handler) {
463+
return false;
464+
}
465+
439466
$id = $this->currentSession->getId();
440467
$contents = $this->encode();
441468

0 commit comments

Comments
 (0)