StringUtils   A
last analyzed

Complexity

Total Complexity 21

Size/Duplication

Total Lines 110
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 2

Importance

Changes 0
Metric Value
dl 0
loc 110
c 0
b 0
f 0
wmc 21
lcom 0
cbo 2
rs 10

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A equals() 0 25 4
A length() 0 13 3
A substring() 0 15 4
B payload2string() 0 18 9
1
<?php
2
3
/*
4
 * This file is part of the tmilos/jose-jwt package.
5
 *
6
 * (c) Milos Tomic <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Tmilos\JoseJwt\Util;
13
14
use Tmilos\JoseJwt\Error\JoseJwtException;
15
use Tmilos\JoseJwt\Json\JsonMapper;
16
17
class StringUtils
18
{
19
    private function __construct()
20
    {
21
    }
22
23
    /**
24
     * Compares two strings.
25
     *
26
     * This method implements a constant-time algorithm to compare strings.
27
     * Regardless of the used implementation, it will leak length information.
28
     *
29
     * @param string $knownString The string of known length to compare against
30
     * @param string $userInput   The string that the user can control
31
     *
32
     * @return bool true if the two strings are the same, false otherwise
33
     */
34
    public static function equals($knownString, $userInput)
35
    {
36
        static $exists = null;
37
        if (null === $exists) {
38
            $exists = function_exists('hash_equals');
39
        }
40
        $knownString = (string) $knownString;
41
        $userInput = (string) $userInput;
42
        if ($exists) {
43
            return hash_equals($knownString, $userInput);
44
        }
45
        $knownLen = strlen($knownString);
46
        $userLen = strlen($userInput);
47
        // Extend the known string to avoid uninitialized string offsets
48
        $knownString .= $userInput;
49
        // Set the result to the difference between the lengths
50
        $result = $knownLen - $userLen;
51
        // Note that we ALWAYS iterate over the user-supplied length
52
        // This is to mitigate leaking length information
53
        for ($i = 0; $i < $userLen; ++$i) {
54
            $result |= (ord($knownString[$i]) ^ ord($userInput[$i]));
55
        }
56
        // They are only identical strings if $result is exactly 0...
57
        return 0 === $result;
58
    }
59
60
    /**
61
     * @param string $value
62
     *
63
     * @return int
64
     */
65
    public static function length($value)
66
    {
67
        static $exists = null;
68
        if (null === $exists) {
69
            $exists = function_exists('mb_strlen');
70
        }
71
72
        if ($exists) {
73
            return mb_strlen($value, '8bit');
74
        }
75
76
        return strlen($value);
77
    }
78
79
    /**
80
     * @param string $value
81
     * @param int    $start
82
     * @param int    $length
83
     *
84
     * @return string
85
     */
86
    public static function substring($value, $start = 0, $length = null)
87
    {
88
        static $exists = null;
89
        if (null === $exists) {
90
            $exists = function_exists('mb_substr');
91
        }
92
93
        if ($exists) {
94
            return mb_substr($value, $start, $length, '8bit');
95
        } elseif ($length !== null) {
96
            return substr($value, $start, $length);
97
        }
98
99
        return substr($value, $start);
100
    }
101
102
    /**
103
     * @param string|array|object $payload
104
     * @param JsonMapper          $mapper
105
     *
106
     * @return string
107
     */
108
    public static function payload2string($payload, JsonMapper $mapper = null)
109
    {
110
        if (is_array($payload)) {
111
            return json_encode($payload, JSON_UNESCAPED_SLASHES);
112
        } elseif (is_string($payload) || null === $payload) {
113
            if (trim($payload) !== '') {
114
                return $payload;
115
            } else {
116
                throw new JoseJwtException('Payload can not be empty');
117
            }
118
        } elseif (is_object($payload) && $payload instanceof \JsonSerializable) {
119
            return json_encode($payload, JSON_UNESCAPED_SLASHES);
120
        } elseif (is_object($payload) && $mapper) {
121
            return $mapper->getJsonString($payload);
122
        }
123
124
        throw new JoseJwtException('Unable to serialize payload');
125
    }
126
}
127