Passed
Push — master ( e27b1e...bbd427 )
by Tim
01:42
created

Assert::validURL()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 4
c 1
b 0
f 0
nc 2
nop 2
dl 0
loc 6
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\Assert;
6
7
use BadMethodCallException;
8
use DateTimeImmutable;
9
use InvalidArgumentException;
10
use Throwable;
11
use Webmozart\Assert\Assert as Webmozart;
12
13
use function array_map;
14
use function array_pop;
15
use function base64_decode;
16
use function base64_encode;
17
use function call_user_func_array;
18
use function end;
19
use function filter_var;
20
use function get_class;
21
use function implode;
22
use function in_array;
23
use function is_string;
24
use function is_object;
25
use function is_resource;
26
use function is_subclass_of;
27
use function lcfirst;
28
use function method_exists;
29
use function preg_match;
30
use function sprintf;
31
32
/**
33
 * Webmozart\Assert wrapper class
34
 *
35
 * @package simplesamlphp/assert
36
 *
37
 * @method static void string(mixed $value, string $message = '', class-string $exception = '')
38
 * @method static void stringNotEmpty(mixed $value, string $message = '', class-string $exception = '')
39
 * @method static void integer(mixed $value, string $message = '', class-string $exception = '')
40
 * @method static void integerish(mixed $value, string $message = '', class-string $exception = '')
41
 * @method static void positiveInteger(mixed $value, string $message = '', class-string $exception = '')
42
 * @method static void float(mixed $value, string $message = '', class-string $exception = '')
43
 * @method static void numeric(mixed $value, string $message = '', class-string $exception = '')
44
 * @method static void natural(mixed $value, string $message = '', class-string $exception = '')
45
 * @method static void boolean(mixed $value, string $message = '', class-string $exception = '')
46
 * @method static void scalar(mixed $value, string $message = '', class-string $exception = '')
47
 * @method static void object(mixed $value, string $message = '', class-string $exception = '')
48
 * @method static void resource(mixed $value, string|null $type, string $message = '', class-string $exception = '')
49
 * @method static void isCallable(mixed $value, string $message = '', class-string $exception = '')
50
 * @method static void isArray(mixed $value, string $message = '', class-string $exception = '')
51
 * @method static void isTraversable(mixed $value, string $message = '', class-string $exception = '')
52
 * @method static void isArrayAccessible(mixed $value, string $message = '', class-string $exception = '')
53
 * @method static void isCountable(mixed $value, string $message = '', class-string $exception = '')
54
 * @method static void isIterable(mixed $value, string $message = '', class-string $exception = '')
55
 * @method static void isInstanceOf(mixed $value, string|object $class, string $message = '', class-string $exception = '')
56
 * @method static void notInstanceOf(mixed $value, string|object $class, string $message = '', class-string $exception = '')
57
 * @method static void isInstanceOfAny(mixed $value, array<object|string> $classes, string $message = '', class-string $exception = '')
58
 * @method static void isAOf(string|object $value, string $class, string $message = '', class-string $exception = '')
59
 * @method static void isNotA(string|object $value, string $class, string $message = '', class-string $exception = '')
60
 * @method static void isAnyOf(string|object $value, string[] $classes, string $message = '', class-string $exception = '')
61
 * @method static void isEmpty(mixed $value, string $message = '', class-string $exception = '')
62
 * @method static void notEmpty(mixed $value, string $message = '', class-string $exception = '')
63
 * @method static void null(mixed $value, string $message = '', class-string $exception = '')
64
 * @method static void notNull(mixed $value, string $message = '', class-string $exception = '')
65
 * @method static void true(mixed $value, string $message = '', class-string $exception = '')
66
 * @method static void false(mixed $value, string $message = '', class-string $exception = '')
67
 * @method static void notFalse(mixed $value, string $message = '', class-string $exception = '')
68
 * @method static void ip(mixed $value, string $message = '', class-string $exception = '')
69
 * @method static void ipv4(mixed $value, string $message = '', class-string $exception = '')
70
 * @method static void ipv6(mixed $value, string $message = '', class-string $exception = '')
71
 * @method static void email(mixed $value, string $message = '', class-string $exception = '')
72
 * @method static void uniqueValues(array $values, string $message = '', class-string $exception = '')
73
 * @method static void eq(mixed $value, mixed $expect, string $message = '', class-string $exception = '')
74
 * @method static void notEq(mixed $value, mixed $expect, string $message = '', class-string $exception = '')
75
 * @method static void same(mixed $value, mixed $expect, string $message = '', class-string $exception = '')
76
 * @method static void notSame(mixed $value, mixed $expect, string $message = '', class-string $exception = '')
77
 * @method static void greaterThan(mixed $value, mixed $limit, string $message = '', class-string $exception = '')
78
 * @method static void greaterThanEq(mixed $value, mixed $limit, string $message = '', class-string $exception = '')
79
 * @method static void lessThan(mixed $value, mixed $limit, string $message = '', class-string $exception = '')
80
 * @method static void lessThanEq(mixed $value, mixed $limit, string $message = '', class-string $exception = '')
81
 * @method static void range(mixed $value, mixed $min, mixed $max, string $message = '', class-string $exception = '')
82
 * @method static void oneOf(mixed $value, array $values, string $message = '', class-string $exception = '')
83
 * @method static void inArray(mixed $value, mixed $values, string $message = '', class-string $exception = '')
84
 * @method static void contains(string $value, string $subString, string $message = '', class-string $exception = '')
85
 * @method static void notContains(string $value, string $subString, string $message = '', class-string $exception = '')
86
 * @method static void notWhitespaceOnly($value, string $message = '', class-string $exception = '')
87
 * @method static void startsWith(string $value, string $prefix, string $message = '', class-string $exception = '')
88
 * @method static void notStartsWith(string $value, string $prefix, string $message = '', class-string $exception = '')
89
 * @method static void startsWithLetter(mixed $value, string $message = '', class-string $exception = '')
90
 * @method static void endsWith(string $value, string $suffix, string $message = '', class-string $exception = '')
91
 * @method static void notEndsWith(string $value, string $suffix, string $message = '', class-string $exception = '')
92
 * @method static void regex(string $value, string $pattern, string $message = '', class-string $exception = '')
93
 * @method static void notRegex(string $value, string $pattern, string $message = '', class-string $exception = '')
94
 * @method static void unicodeLetters(mixed $value, string $message = '', class-string $exception = '')
95
 * @method static void alpha(mixed $value, string $message = '', class-string $exception = '')
96
 * @method static void digits(string $value, string $message = '', class-string $exception = '')
97
 * @method static void alnum(string $value, string $message = '', class-string $exception = '')
98
 * @method static void lower(string $value, string $message = '', class-string $exception = '')
99
 * @method static void upper(string $value, string $message = '', class-string $exception = '')
100
 * @method static void length(string $value, int $length, string $message = '', class-string $exception = '')
101
 * @method static void minLength(string $value, int|float $min, string $message = '', class-string $exception = '')
102
 * @method static void maxLength(string $value, int|float $max, string $message = '', class-string $exception = '')
103
 * @method static void lengthBetween(string $value, int|float $min, int|float $max, string $message = '', class-string $exception = '')
104
 * @method static void fileExists(mixed $value, string $message = '', class-string $exception = '')
105
 * @method static void file(mixed $value, string $message = '', class-string $exception = '')
106
 * @method static void directory(mixed $value, string $message = '', class-string $exception = '')
107
 * @method static void readable(string $value, string $message = '', class-string $exception = '')
108
 * @method static void writable(string $value, string $message = '', class-string $exception = '')
109
 * @method static void classExists(mixed $value, string $message = '', class-string $exception = '')
110
 * @method static void subclassOf(mixed $value, string|object $class, string $message = '', class-string $exception = '')
111
 * @method static void interfaceExists(mixed $value, string $message = '', class-string $exception = '')
112
 * @method static void implementsInterface(mixed $value, mixed $interface, string $message = '', class-string $exception = '')
113
 * @method static void propertyExists(string|object $classOrObject, mixed $property, string $message = '', class-string $exception = '')
114
 * @method static void propertyNotExists(string|object $classOrObject, mixed $property, string $message = '', class-string $exception = '')
115
 * @method static void methodExists(string|object $classOrObject, mixed $method, string $message = '', class-string $exception = '')
116
 * @method static void methodNotExists(string|object $classOrObject, mixed $method, string $message = '', class-string $exception = '')
117
 * @method static void keyExists(array $array, string|int $key, string $message = '', class-string $exception = '')
118
 * @method static void keyNotExists(array $array, string|int $key, string $message = '', class-string $exception = '')
119
 * @method static void validArrayKey($value, string $message = '', class-string $exception = '')
120
 * @method static void count(Countable|array $array, int $number, string $message = '', class-string $exception = '')
121
 * @method static void minCount(Countable|array $array, int|float $min, string $message = '', class-string $exception = '')
122
 * @method static void maxCount(Countable|array $array, int|float $max, string $message = '', class-string $exception = '')
123
 * @method static void countBetween(Countable|array $array, int|float $min, int|float $max, string $message = '', class-string $exception = '')
124
 * @method static void isList(mixed $array, string $message = '', class-string $exception = '')
125
 * @method static void isNonEmptyList(mixed $array, string $message = '', class-string $exception = '')
126
 * @method static void isMap(mixed $array, string $message = '', class-string $exception = '')
127
 * @method static void isNonEmptyMap(mixed $array, string $message = '', class-string $exception = '')
128
 * @method static void uid(string $value, string $message = '', class-string $exception = '')
129
 * @method static void throws(Closure $expression, string $class = 'Exception', string $message = '', class-string $exception = '')
130
 *
131
 * @method static void nullOrString(mixed $value, string $message = '', class-string $exception = '')
132
 * @method static void allString(mixed $value, string $message = '', class-string $exception = '')
133
 * @method static void nullOrStringNotEmpty(mixed $value, string $message = '', class-string $exception = '')
134
 * @method static void allOrStringNotEmpty(mixed $value, string $message = '', class-string $exception = '')
135
 * @method static void nullOrInteger(mixed $value, string $message = '', class-string $exception = '')
136
 * @method static void allInteger(mixed $value, string $message = '', class-string $exception = '')
137
 * @method static void nullOrIntegerish(mixed $value, string $message = '', class-string $exception = '')
138
 * @method static void allIntegerish(mixed $value, string $message = '', class-string $exception = '')
139
 * @method static void nullOrPositiveInteger(mixed $value, string $message = '', class-string $exception = '')
140
 * @method static void allPositiveInteger(mixed $value, string $message = '', class-string $exception = '')
141
 * @method static void nullOrFloat(mixed $value, string $message = '', class-string $exception = '')
142
 * @method static void allFloat(mixed $value, string $message = '', class-string $exception = '')
143
 * @method static void nullOrNumeric(mixed $value, string $message = '', class-string $exception = '')
144
 * @method static void allNumeric(mixed $value, string $message = '', class-string $exception = '')
145
 * @method static void nullOrNatural(mixed $value, string $message = '', class-string $exception = '')
146
 * @method static void allNatural(mixed $value, string $message = '', class-string $exception = '')
147
 * @method static void nullOrBoolean(mixed $value, string $message = '', class-string $exception = '')
148
 * @method static void allBoolean(mixed $value, string $message = '', class-string $exception = '')
149
 * @method static void nullOrScalar(mixed $value, string $message = '', class-string $exception = '')
150
 * @method static void allScalar(mixed $value, string $message = '', class-string $exception = '')
151
 * @method static void nullOrObject(mixed $value, string $message = '', class-string $exception = '')
152
 * @method static void allObject(mixed $value, string $message = '', class-string $exception = '')
153
 * @method static void nullOrResource(mixed $value, string|null $type, string $message = '', class-string $exception = '')
154
 * @method static void allResource(mixed $value, string|null $type, string $message = '', class-string $exception = '')
155
 * @method static void nullOrIsCallable(mixed $value, string $message = '', class-string $exception = '')
156
 * @method static void allIsCallable(mixed $value, string $message = '', class-string $exception = '')
157
 * @method static void nullOrIsArray(mixed $value, string $message = '', class-string $exception = '')
158
 * @method static void allIsArray(mixed $value, string $message = '', class-string $exception = '')
159
 * @method static void nullOrIsTraversable(mixed $value, string $message = '', class-string $exception = '')
160
 * @method static void allIsTraversable(mixed $value, string $message = '', class-string $exception = '')
161
 * @method static void nullOrIsArrayAccessible(mixed $value, string $message = '', class-string $exception = '')
162
 * @method static void allIsArrayAccessible(mixed $value, string $message = '', class-string $exception = '')
163
 * @method static void nullOrIsCountable(mixed $value, string $message = '', class-string $exception = '')
164
 * @method static void allIsCountable(mixed $value, string $message = '', class-string $exception = '')
165
 * @method static void nullOrIsIterable(mixed $value, string $message = '', class-string $exception = '')
166
 * @method static void allIsIterable(mixed $value, string $message = '', class-string $exception = '')
167
 * @method static void nullOrIsInstanceOf(mixed $value, string|object $class, string $message = '', class-string $exception = '')
168
 * @method static void allIsInstanceOf(mixed $value, string|object $class, string $message = '', class-string $exception = '')
169
 * @method static void nullOrNotInstanceOf(mixed $value, string|object $class, string $message = '', class-string $exception = '')
170
 * @method static void allNotInstanceOf(mixed $value, string|object $class, string $message = '', class-string $exception = '')
171
 * @method static void nullOrIsInstanceOfAny(mixed $value, array<object|string> $classes, string $message = '', class-string $exception = '')
172
 * @method static void allIsInstanceOfAny(mixed $value, array<object|string> $classes, string $message = '', class-string $exception = '')
173
 * @method static void nullOrIsAOf(object|string|null $value, string $class, string $message = '', class-string $exception = '')
174
 * @method static void allIsAOf(object|string|null $value, string $class, string $message = '', class-string $exception = '')
175
 * @method static void nullOrIsNotA(object|string|null $value, string $class, string $message = '', class-string $exception = '')
176
 * @method static void allIsNotA(iterable<object|string> $value, string $class, string $message = '', class-string $exception = '')
177
 * @method static void nullOrIsAnyOf(object|string|null $value, string[] $classes, string $message = '', class-string $exception = '')
178
 * @method static void allIsAnyOf(iterable<object|string> $value, string[] $classes, string $message = '', class-string $exception = '')
179
 * @method static void nullOrIsEmpty(mixed $value, string $message = '', class-string $exception = '')
180
 * @method static void allIsEmpty(mixed $value, string $message = '', class-string $exception = '')
181
 * @method static void nullOrNotEmpty(mixed $value, string $message = '', class-string $exception = '')
182
 * @method static void allNotEmpty(mixed $value, string $message = '', class-string $exception = '')
183
 * @method static void allNull(mixed $value, string $message = '', class-string $exception = '')
184
 * @method static void allNotNull(mixed $value, string $message = '', class-string $exception = '')
185
 * @method static void nullOrTrue(mixed $value, string $message = '', class-string $exception = '')
186
 * @method static void allTrue(mixed $value, string $message = '', class-string $exception = '')
187
 * @method static void nullOrFalse(mixed $value, string $message = '', class-string $exception = '')
188
 * @method static void allFalse(mixed $value, string $message = '', class-string $exception = '')
189
 * @method static void nullOrNotFalse(mixed $value, string $message = '', class-string $exception = '')
190
 * @method static void allNotFalse(mixed $value, string $message = '', class-string $exception = '')
191
 * @method static void nullOrIp(mixed $value, string $message = '', class-string $exception = '')
192
 * @method static void allIp(mixed $value, string $message = '', class-string $exception = '')
193
 * @method static void nullOrIpv4(mixed $value, string $message = '', class-string $exception = '')
194
 * @method static void allIpv4(mixed $value, string $message = '', class-string $exception = '')
195
 * @method static void nullOrIpv6(mixed $value, string $message = '', class-string $exception = '')
196
 * @method static void allIpv6(mixed $value, string $message = '', class-string $exception = '')
197
 * @method static void nullOrEmail(mixed $value, string $message = '', class-string $exception = '')
198
 * @method static void allEmail(mixed $value, string $message = '', class-string $exception = '')
199
 * @method static void nullOrUniqueValues(array|null $values, string $message = '', class-string $exception = '')
200
 * @method static void allUniqueValues(iterable<array> $values, string $message = '', class-string $exception = '')
201
 * @method static void nullOrEq(mixed $value, mixed $expect, string $message = '', class-string $exception = '')
202
 * @method static void allEq(mixed $value, mixed $expect, string $message = '', class-string $exception = '')
203
 * @method static void nullOrNotEq(mixed $value, mixed $expect, string $message = '', class-string $exception = '')
204
 * @method static void allNotEq(mixed $value, mixed $expect, string $message = '', class-string $exception = '')
205
 * @method static void nullOrSame(mixed $value, mixed $expect, string $message = '', class-string $exception = '')
206
 * @method static void allSame(mixed $value, mixed $expect, string $message = '', class-string $exception = '')
207
 * @method static void nullOrNotSame(mixed $value, mixed $expect, string $message = '', class-string $exception = '')
208
 * @method static void allNotSame(mixed $value, mixed $expect, string $message = '', class-string $exception = '')
209
 * @method static void nullOrGreaterThan(mixed $value, mixed $limit, string $message = '', class-string $exception = '')
210
 * @method static void allGreaterThan(mixed $value, mixed $limit, string $message = '', class-string $exception = '')
211
 * @method static void nullOrGreaterThanEq(mixed $value, mixed $limit, string $message = '', class-string $exception = '')
212
 * @method static void allGreaterThanEq(mixed $value, mixed $limit, string $message = '', class-string $exception = '')
213
 * @method static void nullOrLessThan(mixed $value, mixed $limit, string $message = '', class-string $exception = '')
214
 * @method static void allLessThan(mixed $value, mixed $limit, string $message = '', class-string $exception = '')
215
 * @method static void nullOrLessThanEq(mixed $value, mixed $limit, string $message = '', class-string $exception = '')
216
 * @method static void allLessThanEq(mixed $value, mixed $limit, string $message = '', class-string $exception = '')
217
 * @method static void nullOrRange(mixed $value, mixed $min, mixed $max, string $message = '', class-string $exception = '')
218
 * @method static void allRange(mixed $value, mixed $min, mixed $max, string $message = '', class-string $exception = '')
219
 * @method static void nullOrOneOf(mixed $value, array $values, string $message = '', class-string $exception = '')
220
 * @method static void allOneOf(mixed $value, array $values, string $message = '', class-string $exception = '')
221
 * @method static void nullOrInArray(mixed $value, array $values, string $message = '', class-string $exception = '')
222
 * @method static void allInArray(mixed $value, array $values, string $message = '', class-string $exception = '')
223
 * @method static void nullOrContains(string|null $value, string $subString, string $message = '', class-string $exception = '')
224
 * @method static void allContains(iterable<string> $value, string $subString, string $message = '', class-string $exception = '')
225
 * @method static void nullOrNotContains(string|null $value, string $subString, string $message = '', class-string $exception = '')
226
 * @method static void allNotContains(iterable<string> $value, string $subString, string $message = '', class-string $exception = '')
227
 * @method static void nullOrWhitespaceOnly(string|null $value, string $message = '', class-string $exception = '')
228
 * @method static void allWhitespaceOnly(iterable<string> $value, string $message = '', class-string $exception = '')
229
 * @method static void nullOrStartsWith(string|null $value, string $prefix, string $message = '', class-string $exception = '')
230
 * @method static void allStartsWith(iterable<string> $value, string $prefix, string $message = '', class-string $exception = '')
231
 * @method static void nullOrNotStartsWith(string|null $value, string $prefix, string $message = '', class-string $exception = '')
232
 * @method static void allNotStartsWith(iterable<string> $value, string $prefix, string $message = '', class-string $exception = '')
233
 * @method static void nullOrStartsWithLetter(mixed $value, string $message = '', class-string $exception = '')
234
 * @method static void allStartsWithLetter(mixed $value, string $message = '', class-string $exception = '')
235
 * @method static void nullOrEndsWith(string|null $value, string $suffix, string $message = '', class-string $exception = '')
236
 * @method static void allEndsWith(iterable<string> $value, string $suffix, string $message = '', class-string $exception = '')
237
 * @method static void nullOrNotEndsWith(string|null $value, string $suffix, string $message = '', class-string $exception = '')
238
 * @method static void allNotEndsWith(iterable<string> $value, string $suffix, string $message = '', class-string $exception = '')
239
 * @method static void nullOrRegex(string|null $value, string $prefix, string $message = '', class-string $exception = '')
240
 * @method static void allRegEx(iterable<string> $value, string $prefix, string $message = '', class-string $exception = '')
241
 * @method static void nullOrNotRegex(string|null $value, string $prefix, string $message = '', class-string $exception = '')
242
 * @method static void allNotRegEx(iterable<string> $value, string $prefix, string $message = '', class-string $exception = '')
243
 * @method static void nullOrUnicodeLetters(mixed $value, string $message = '', class-string $exception = '')
244
 * @method static void allUnicodeLetters(mixed $value, string $message = '', class-string $exception = '')
245
 * @method static void nullOrAlpha(mixed $value, string $message = '', class-string $exception = '')
246
 * @method static void allAlpha(mixed $value, string $message = '', class-string $exception = '')
247
 * @method static void nullOrDigits(string|null $value, string $message = '', class-string $exception = '')
248
 * @method static void allDigits(iterable<string> $value, string $message = '', class-string $exception = '')
249
 * @method static void nullOrAlnum(string|null $value, string $message = '', class-string $exception = '')
250
 * @method static void allAlnum(iterable<string> $value, string $message = '', class-string $exception = '')
251
 * @method static void nullOrLower(string|null $value, string $message = '', class-string $exception = '')
252
 * @method static void allLower(iterable<string> $value, string $message = '', class-string $exception = '')
253
 * @method static void nullOrUpper(string|null $value, string $message = '', class-string $exception = '')
254
 * @method static void allUpper(iterable<string> $value, string $message = '', class-string $exception = '')
255
 * @method static void nullOrLength(string|null $value, int $length, string $message = '', class-string $exception = '')
256
 * @method static void allLength(iterable<string> $value, int $length, string $message = '', class-string $exception = '')
257
 * @method static void nullOrMinLength(string|null $value, int|float $min, string $message = '', class-string $exception = '')
258
 * @method static void allMinLength(iterable<string> $value, int|float $min, string $message = '', class-string $exception = '')
259
 * @method static void nullOrMaxLength(string|null $value, int|float $max, string $message = '', class-string $exception = '')
260
 * @method static void allMaxLength(iterable<string> $value, int|float $max, string $message = '', class-string $exception = '')
261
 * @method static void nullOrLengthBetween(string|null $value, int|float $min, int|float $max, string $message = '', class-string $exception = '')
262
 * @method static void allLengthBetween(iterable<string> $value, int|float $min, int|float $max, string $message = '', class-string $exception = '')
263
 * @method static void nullOrFileExists(mixed $value, string $message = '', class-string $exception = '')
264
 * @method static void allFileExists(mixed $value, string $message = '', class-string $exception = '')
265
 * @method static void nullOrFile(mixed $value, string $message = '', class-string $exception = '')
266
 * @method static void allFile(mixed $value, string $message = '', class-string $exception = '')
267
 * @method static void nullOrDirectory(mixed $value, string $message = '', class-string $exception = '')
268
 * @method static void allDirectory(mixed $value, string $message = '', class-string $exception = '')
269
 * @method static void nullOrReadable(string|null $value, string $message = '', class-string $exception = '')
270
 * @method static void allReadable(iterable<string> $value, string $message = '', class-string $exception = '')
271
 * @method static void nullOrWritable(string|null $value, string $message = '', class-string $exception = '')
272
 * @method static void allWritable(iterable<string> $value, string $message = '', class-string $exception = '')
273
 * @method static void nullOrClassExists(mixed $value, string $message = '', class-string $exception = '')
274
 * @method static void allClassExists(mixed $value, string $message = '', class-string $exception = '')
275
 * @method static void nullOrSubclassOf(mixed $value, string|object $class, string $message = '', class-string $exception = '')
276
 * @method static void allSubclassOf(mixed $value, string|object $class, string $message = '', class-string $exception = '')
277
 * @method static void nullOrInterfaceExists(mixed $value, string $message = '', class-string $exception = '')
278
 * @method static void allInterfaceExists(mixed $value, string $message = '', class-string $exception = '')
279
 * @method static void nullOrImplementsInterface(mixed $value, mixed $interface, string $message = '', class-string $exception = '')
280
 * @method static void allImplementsInterface(mixed $value, mixed $interface, string $message = '', class-string $exception = '')
281
 * @method static void nullOrPropertyExists(string|object|null $classOrObject, mixed $property, string $message = '', class-string $exception = '')
282
 * @method static void allPropertyExists(iterable<string|object> $classOrObject, mixed $property, string $message = '', class-string $exception = '')
283
 * @method static void nullOrPropertyNotExists(string|object|null $classOrObject, mixed $property, string $message = '', class-string $exception = '')
284
 * @method static void allPropertyNotExists(iterable<string|object> $classOrObject, mixed $property, string $message = '', class-string $exception = '')
285
 * @method static void nullOrMethodExists(string|object|null $classOrObject, mixed $method, string $message = '', class-string $exception = '')
286
 * @method static void allMethodExists(iterable<string|object> $classOrObject, mixed $method, string $message = '', class-string $exception = '')
287
 * @method static void nullOrMethodNotExists(string|object|null $classOrObject, mixed $method, string $message = '', class-string $exception = '')
288
 * @method static void allMethodNotExists(iterable<string|object> $classOrObject, mixed $method, string $message = '', class-string $exception = '')
289
 * @method static void nullOrKeyExists(array|null $array, string|int $key, string $message = '', class-string $exception = '')
290
 * @method static void allKeyExists(iterable<array> $array, string|int $key, string $message = '', class-string $exception = '')
291
 * @method static void nullOrKeyNotExists(array|null $array, string|int $key, string $message = '', class-string $exception = '')
292
 * @method static void allKeyNotExists(iterable<array> $array, string|int $key, string $message = '', class-string $exception = '')
293
 * @method static void nullOrValidArrayKey(mixed $value, string $message = '', class-string $exception = '')
294
 * @method static void allValidArrayKey(mixed $value, string $message = '', class-string $exception = '')
295
 * @method static void nullOrCount(Countable|array|null $array, int $number, string $message = '', class-string $exception = '')
296
 * @method static void allCount(iterable<Countable|array> $array, int $number, string $message = '', class-string $exception = '')
297
 * @method static void nullOrMinCount(Countable|array|null $array, int|float $min, string $message = '', class-string $exception = '')
298
 * @method static void allMinCount(iterable<Countable|array> $array, int|float $min, string $message = '', class-string $exception = '')
299
 * @method static void nullOrMaxCount(Countable|array|null $array, int|float $max, string $message = '', class-string $exception = '')
300
 * @method static void allMaxCount(iterable<Countable|array> $array, int|float $max, string $message = '', class-string $exception = '')
301
 * @method static void nullOrCountBetween(Countable|array|null $array, int|float $min, int|float $max, string $message = '', class-string $exception = '')
302
 * @method static void allCountBetween(iterable<Countable|array> $array, int|float $min, int|float $max, string $message = '', class-string $exception = '')
303
 * @method static void nullOrIsList(mixed $array, string $message = '', class-string $exception = '')
304
 * @method static void allIsList(mixed $array, string $message = '', class-string $exception = '')
305
 * @method static void nullOrIsNonEmptyList(mixed $array, string $message = '', class-string $exception = '')
306
 * @method static void allIsNonEmptyList(mixed $array, string $message = '', class-string $exception = '')
307
 * @method static void nullOrIsMap(mixed $array, string $message = '', class-string $exception = '')
308
 * @method static void allIsMap(mixed $array, string $message = '', class-string $exception = '')
309
 * @method static void nullOrIsNonEmptyMap(mixed $array, string $message = '', class-string $exception = '')
310
 * @method static void allIsNonEmptyMap(mixed $array, string $message = '', class-string $exception = '')
311
 * @method static void nullOrUuid(string|null $value, string $message = '', class-string $exception = '')
312
 * @method static void allUuid(iterable<string> $value, string $message = '', class-string $exception = '')
313
 * @method static void nullOrThrows(Closure|null $expression, string $class, string $message = '', class-string $exception = '')
314
 * @method static void allThrows(iterable<Closure> $expression, string $class, string $message = '', class-string $exception = '')
315
 */
1 ignored issue
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
316
final class Assert
317
{
318
    private static string $duration_regex = '/^(-?)P(?=.)((\d+)Y)?((\d+)M)?((\d+)D)?(T(?=.)((\d+)H)?((\d+)M)?(\d*(\.\d+)?S)?)?$/i';
319
320
    private static string $qname_regex = '/^[a-zA-Z_][\w.-]*:[a-zA-Z_][\w.-]*$/';
321
322
    private static string $ncname_regex = '/^[a-zA-Z_][\w.-]*$/';
323
324
    private static string $base64_regex = '/^(?:[a-z0-9+\/]{4})*(?:[a-z0-9+\/]{2}==|[a-z0-9+\/]{3}=)?$/i';
325
326
    private static string $uri_same_document_regex = '/^#([a-z0-9-._~!$&\'()*+,;=:!\/?]|%[a-f0-9]{2})*$/i';
327
328
    private static string $urn_regex = '/\A(?i:urn:(?!urn:)(?<nid>[a-z0-9][a-z0-9-]{1,31}):(?<nss>(?:[-a-z0-9()+,.:=@;$_!*\'&~\/]|%[0-9a-f]{2})+)(?:\?\+(?<rcomponent>.*?))?(?:\?=(?<qcomponent>.*?))?(?:#(?<fcomponent>.*?))?)\z/';
329
330
331
    /**
332
     * @param string $name
333
     * @param array $arguments
334
     */
335
    public static function __callStatic(string $name, array $arguments): void
336
    {
337
        // Handle Exception-parameter
338
        $exception = AssertionFailedException::class;
339
340
        $last = end($arguments);
341
        if (is_string($last) && class_exists($last) && is_subclass_of($last, Throwable::class)) {
342
            $exception = $last;
343
            array_pop($arguments);
344
        }
345
346
        try {
347
            // Putting Webmozart first, since the most calls will be to their native assertions
348
            if (method_exists(Webmozart::class, $name)) {
349
                call_user_func_array([Webmozart::class, $name], $arguments);
350
            } else if (method_exists(static::class, $name)) {
351
                call_user_func_array([static::class, $name], $arguments);
352
            } else if (preg_match('/^nullOr(.*)$/i', $name, $matches)) {
353
                $method = lcfirst($matches[1]);
354
                if (method_exists(static::class, $method)) {
355
                    call_user_func_array([static::class, 'nullOr'], [$method, $arguments]);
356
                }
357
            } else {
358
                throw new BadMethodCallException();
359
            }
360
        } catch (InvalidArgumentException $e) {
361
            throw new $exception($e->getMessage());
362
        }
363
    }
364
365
366
    /***********************************************************************************
367
     *  NOTE:  Custom assertions may be added below this line.                         *
368
     *         They SHOULD be marked as `private` to ensure the call is forced         *
369
     *          through __callStatic().                                                *
370
     *         Assertions marked `public` are called directly and will                 *
371
     *          not handle any custom exception passed to it.                          *
372
     ***********************************************************************************/
373
374
375
    /**
376
     * nullOr* for our custom assertions
377
     *
378
     * @param string $method
379
     * @param array $arguments
380
     * @return void
381
     */
382
    private static function nullOr(string $method, array $arguments): void
383
    {
384
        $value = reset($arguments);
385
        ($value === null) || call_user_func_array([static::class, $method], $arguments);
386
    }
387
388
389
    /**
390
     * @param string $value
391
     */
392
    private static function validDuration(string $value, string $message = ''): void
393
    {
394
        if (filter_var($value, FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => self::$duration_regex]]) === false) {
395
            throw new InvalidArgumentException(sprintf(
396
                $message ?: '\'%s\' is not a valid xs:duration',
397
                $value
398
            ));
399
        }
400
    }
401
402
403
    /**
404
     * Note: This test is not bullet-proof but prevents a string containing illegal characters
405
     * from being passed and ensures the string roughly follows the correct format for a Base64 encoded string
406
     *
407
     * @param string $value
408
     * @param string $message
409
     */
410
    private static function stringPlausibleBase64(string $value, string $message = ''): void
411
    {
412
        $result = true;
413
414
        if (filter_var($value, FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => self::$base64_regex]]) === false) {
415
            $result = false;
416
        } elseif (strlen($value) % 4 !== 0) {
417
            $result = false;
418
        } else {
419
            $decoded = base64_decode($value, true);
420
            if ($decoded === false) {
421
                $result = false;
422
            } elseif (base64_encode($decoded) !== $value) {
423
                $result = false;
424
            }
425
        }
426
427
        if ($result === false) {
428
            throw new InvalidArgumentException(sprintf(
429
                $message ?: '\'%s\' is not a valid Base64 encoded string',
430
                $value
431
            ));
432
        }
433
    }
434
435
436
    /**
437
     * @param string $value
438
     * @param string $message
439
     */
440
    private static function validDateTime(string $value, string $message = ''): void
441
    {
442
        if (
443
            DateTimeImmutable::createFromFormat(DateTimeImmutable::ISO8601, $value) === false &&
444
            DateTimeImmutable::createFromFormat(DateTimeImmutable::RFC3339_EXTENDED, $value) === false
445
        ) {
446
            throw new InvalidArgumentException(sprintf(
447
                $message ?: '\'%s\' is not a valid DateTime',
448
                $value
449
            ));
450
        }
451
    }
452
453
454
    /**
455
     * @param string $value
456
     * @param string $message
457
     */
458
    private static function validDateTimeZulu(string $value, string $message = ''): void
459
    {
460
        $dateTime1 = DateTimeImmutable::createFromFormat(DateTimeImmutable::ISO8601, $value);
461
        $dateTime2 = DateTimeImmutable::createFromFormat(DateTimeImmutable::RFC3339_EXTENDED, $value);
462
463
        $dateTime = $dateTime1 ?: $dateTime2;
0 ignored issues
show
introduced by
$dateTime1 is of type DateTimeImmutable, thus it always evaluated to true.
Loading history...
464
        if ($dateTime === false) {
0 ignored issues
show
introduced by
The condition $dateTime === false is always false.
Loading history...
465
            throw new InvalidArgumentException(sprintf(
466
                $message ?: '\'%s\' is not a valid DateTime',
467
                $value
468
            ));
469
        } elseif ($dateTime->getTimezone()->getName() !== 'Z') {
470
            throw new InvalidArgumentException(sprintf(
471
                $message ?: '\'%s\' is not a DateTime expressed in the UTC timezone using the \'Z\' timezone identifier.',
472
                $value
473
            ));
474
        }
475
    }
476
477
478
    /**
479
     * @param mixed $value
480
     * @param array $values
481
     * @param string $message
482
     */
483
    private static function notInArray($value, array $values, string $message = ''): void
484
    {
485
        if (in_array($value, $values, true)) {
486
            throw new InvalidArgumentException(sprintf(
487
                $message ?: 'Expected none of: %2$s. Got: %s',
488
                static::valueToString($value),
489
                implode(', ', array_map(['static', 'valueToString'], $values))
490
            ));
491
        }
492
    }
493
494
495
    /**
496
     * @param string $value
497
     * @param string $message
498
     */
499
    private static function validURN(string $value, string $message = ''): void
500
    {
501
        if (filter_var($value, FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => self::$urn_regex]]) === false) {
502
            throw new InvalidArgumentException(sprintf(
503
                $message ?: '\'%s\' is not a valid RFC8141 compliant URN',
504
                $value
505
            ));
506
        }
507
    }
508
509
510
    /**
511
     * @param string $value
512
     * @param string $message
513
     */
514
    private static function validURL(string $value, string $message = ''): void
515
    {
516
        if (filter_var($value, FILTER_VALIDATE_URL) === false) {
517
            throw new InvalidArgumentException(sprintf(
518
                $message ?: '\'%s\' is not a valid RFC2396 compliant URL',
519
                $value
520
            ));
521
        }
522
    }
523
524
525
    /**
526
     * @param string $value
527
     * @param string $message
528
     */
529
    private static function validURI(string $value, string $message = ''): void
530
    {
531
        if (
532
            filter_var($value, FILTER_VALIDATE_URL) === false &&
533
            filter_var($value, FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => self::$urn_regex]]) === false &&
534
            filter_var($value, FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => self::$uri_same_document_regex]]) === false
535
        ) {
536
            throw new InvalidArgumentException(sprintf(
537
                $message ?: '\'%s\' is not a valid RFC3986 compliant URI',
538
                $value
539
            ));
540
        }
541
    }
542
543
544
    /**
545
     * @param string $value
546
     * @param string $message
547
     */
548
    private static function validNCName(string $value, string $message = ''): void
549
    {
550
        if (filter_var($value, FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => self::$ncname_regex]]) === false) {
551
            throw new InvalidArgumentException(sprintf(
552
                $message ?: '\'%s\' is not a valid non-colonized name (NCName)',
553
                $value
554
            ));
555
        }
556
    }
557
558
559
    /**
560
     * @param string $value
561
     * @param string $message
562
     */
563
    private static function validQName(string $value, string $message = ''): void
564
    {
565
        if (filter_var($value, FILTER_VALIDATE_REGEXP, ['options' => ['regexp' => self::$qname_regex]]) === false) {
566
            throw new InvalidArgumentException(sprintf(
567
                $message ?: '\'%s\' is not a valid qualified name (QName)',
568
                $value
569
            ));
570
        }
571
    }
572
573
574
    /**
575
     * @param mixed $value
576
     *
577
     * @return string
578
     */
579
    protected static function valueToString($value): string
580
    {
581
        if (null === $value) {
582
            return 'null';
583
        }
584
585
        if (true === $value) {
586
            return 'true';
587
        }
588
589
        if (false === $value) {
590
            return 'false';
591
        }
592
593
        if (is_array($value)) {
594
            return 'array';
595
        }
596
597
        if (is_object($value)) {
598
            if (method_exists($value, '__toString')) {
599
                return get_class($value) . ': ' . self::valueToString($value->__toString());
600
            }
601
602
            if ($value instanceof DateTime || $value instanceof DateTimeImmutable) {
0 ignored issues
show
Bug introduced by
The type SimpleSAML\Assert\DateTime was not found. Did you mean DateTime? If so, make sure to prefix the type with \.
Loading history...
603
                return get_class($value) . ': ' . self::valueToString($value->format('c'));
604
            }
605
606
            return get_class($value);
607
        }
608
609
        if (is_resource($value)) {
610
            return 'resource';
611
        }
612
613
        if (is_string($value)) {
614
            return '"' . $value . '"';
615
        }
616
617
        return (string) $value;
618
    }
619
}
620