@@ -24,9 +24,11 @@ public function ensureString(mixed $value, ?string $context = null): string
2424 return (string )$ value ;
2525 }
2626
27- $ error = 'Unsafe string casting, aborting. ' ;
28- $ error .= is_string ($ context ) ? ' Context: ' . $ context : '' ;
29- $ error .= ' Value was: ' . var_export ($ value , true );
27+ $ error = $ this ->prepareErrorMessage (
28+ 'Unsafe string casting, aborting. ' ,
29+ $ value ,
30+ $ context ,
31+ );
3032
3133 throw new InvalidValueException ($ error );
3234 }
@@ -43,9 +45,11 @@ public function ensureNonEmptyString(mixed $value, ?string $context = null): str
4345 return $ value ;
4446 }
4547
46- $ error = 'Empty string value encountered, aborting. ' ;
47- $ error .= is_string ($ context ) ? ' Context: ' . $ context : '' ;
48- $ error .= ' Value was: ' . var_export ($ value , true );
48+ $ error = $ this ->prepareErrorMessage (
49+ 'Empty string value encountered, aborting. ' ,
50+ $ value ,
51+ $ context ,
52+ );
4953
5054 throw new InvalidValueException ($ error );
5155 }
@@ -73,9 +77,11 @@ public function ensureArray(mixed $value, ?string $context = null): array
7377 // Converts object properties to an array
7478 }
7579
76- $ error = 'Unsafe array casting, aborting. ' ;
77- $ error .= is_string ($ context ) ? 'Context: ' . $ context : '' ;
78- $ error .= ' Value was: ' . var_export ($ value , true );
80+ $ error = $ this ->prepareErrorMessage (
81+ 'Unsafe array casting, aborting. ' ,
82+ $ value ,
83+ $ context ,
84+ );
7985
8086 throw new InvalidValueException ($ error );
8187 }
@@ -203,10 +209,148 @@ public function ensureInt(mixed $value, ?string $context = null): int
203209 return (int )$ value ;
204210 }
205211
206- $ error = 'Unsafe integer casting, aborting. ' ;
207- $ error .= is_string ($ context ) ? 'Context: ' . $ context : '' ;
208- $ error .= ' Value was: ' . var_export ($ value , true );
212+ $ error = $ this ->prepareErrorMessage (
213+ 'Unsafe integer casting, aborting. ' ,
214+ $ value ,
215+ $ context ,
216+ );
209217
210218 throw new InvalidValueException ($ error );
211219 }
220+
221+ /**
222+ * @return non-empty-string
223+ * @throws \SimpleSAML\OpenID\Exceptions\InvalidValueException
224+ */
225+ public function enforceRegex (
226+ mixed $ value ,
227+ string $ pattern ,
228+ ?string $ context = null ,
229+ ): string {
230+ $ value = $ this ->ensureNonEmptyString ($ value , $ context );
231+
232+ $ error = $ this ->prepareErrorMessage (
233+ 'Regex match failed, aborting. ' ,
234+ $ value ,
235+ $ context ,
236+ );
237+
238+ preg_match ($ pattern , $ value ) || throw new InvalidValueException ($ error );
239+
240+ return $ value ;
241+ }
242+
243+ /**
244+ * @return non-empty-string
245+ * @throws \SimpleSAML\OpenID\Exceptions\InvalidValueException
246+ */
247+ public function enforceUri (
248+ mixed $ value ,
249+ ?string $ context = null ,
250+ string $ pattern = '/^[^:]+:\/\/?([^\s\/$.?#].[^\s]*)?$/ ' ,
251+ ): string {
252+ try {
253+ $ value = $ this ->enforceRegex ($ value , $ pattern , $ context );
254+ } catch (InvalidValueException ) {
255+ $ error = $ this ->prepareErrorMessage (
256+ 'URI regex match failed, aborting. ' ,
257+ $ value ,
258+ $ context ,
259+ );
260+
261+ throw new InvalidValueException ($ error );
262+ }
263+
264+ return $ value ;
265+ }
266+
267+ /**
268+ * @param mixed[] $array
269+ * @return array<mixed[]>
270+ * @throws \SimpleSAML\OpenID\Exceptions\InvalidValueException
271+ */
272+ public function enforceArrayOfArrays (array $ array , ?string $ context = null ): array
273+ {
274+ foreach ($ array as $ value ) {
275+ if (!is_array ($ value )) {
276+ $ error = $ this ->prepareErrorMessage (
277+ 'Non-array value encountered, aborting. ' ,
278+ $ array ,
279+ $ context ,
280+ );
281+
282+ throw new InvalidValueException ($ error );
283+ }
284+ }
285+
286+ /** @var array<mixed[]> $array */
287+ return $ array ;
288+ }
289+
290+ /**
291+ * @param mixed[] $array
292+ * @return non-empty-array<mixed>
293+ * @throws \SimpleSAML\OpenID\Exceptions\InvalidValueException
294+ */
295+ public function enforceNonEmptyArray (array $ array , ?string $ context = null ): array
296+ {
297+ if ($ array === []) {
298+ $ error = $ this ->prepareErrorMessage (
299+ 'Empty array encountered, aborting. ' ,
300+ $ array ,
301+ $ context ,
302+ );
303+ throw new InvalidValueException ($ error );
304+ }
305+
306+ return $ array ;
307+ }
308+
309+ /**
310+ * @param mixed[] $array
311+ * @return non-empty-array<non-empty-string>
312+ * @throws \SimpleSAML\OpenID\Exceptions\InvalidValueException
313+ */
314+ public function enforceNonEmptyArrayWithValuesAsNonEmptyStrings (array $ array , ?string $ context = null ): array
315+ {
316+ $ array = $ this ->ensureArrayWithValuesAsNonEmptyStrings ($ array , $ context );
317+ $ array = $ this ->enforceNonEmptyArray ($ array , $ context );
318+
319+ /** @var non-empty-array<non-empty-string> $array */
320+ return $ array ;
321+ }
322+
323+ /**
324+ * @param mixed[] $array
325+ * @return non-empty-array<non-empty-array>
326+ * @throws \SimpleSAML\OpenID\Exceptions\InvalidValueException
327+ */
328+ public function enforceNonEmptyArrayOfNonEmptyArrays (array $ array , ?string $ context = null ): array
329+ {
330+ $ array = $ this ->enforceNonEmptyArray ($ array , $ context );
331+
332+ foreach ($ array as $ value ) {
333+ if (!is_array ($ value )) {
334+ $ error = $ this ->prepareErrorMessage (
335+ 'Non-array value encountered, aborting. ' ,
336+ $ array ,
337+ $ context ,
338+ );
339+
340+ throw new InvalidValueException ($ error );
341+ }
342+
343+ $ this ->enforceNonEmptyArray ($ value , $ context );
344+ }
345+
346+ /** @var non-empty-array<non-empty-array> $array */
347+ return $ array ;
348+ }
349+
350+ protected function prepareErrorMessage (string $ message , mixed $ value , ?string $ context = null ): string
351+ {
352+ return $ message .
353+ (is_string ($ context ) ? ' Context: ' . $ context : '' ) .
354+ ' Value was: ' . var_export ($ value , true );
355+ }
212356}
0 commit comments