1: <?php
2: /**
3: * Random_* Compatibility Library
4: * for using the new PHP 7 random_* API in PHP 5 projects
5: *
6: * The MIT License (MIT)
7: *
8: * Copyright (c) 2015 - 2018 Paragon Initiative Enterprises
9: *
10: * Permission is hereby granted, free of charge, to any person obtaining a copy
11: * of this software and associated documentation files (the "Software"), to deal
12: * in the Software without restriction, including without limitation the rights
13: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14: * copies of the Software, and to permit persons to whom the Software is
15: * furnished to do so, subject to the following conditions:
16: *
17: * The above copyright notice and this permission notice shall be included in
18: * all copies or substantial portions of the Software.
19: *
20: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26: * SOFTWARE.
27: */
28:
29: if (!is_callable('RandomCompat_strlen')) {
30: if (
31: defined('MB_OVERLOAD_STRING')
32: &&
33: ((int) ini_get('mbstring.func_overload')) & MB_OVERLOAD_STRING
34: ) {
35: /**
36: * strlen() implementation that isn't brittle to mbstring.func_overload
37: *
38: * This version uses mb_strlen() in '8bit' mode to treat strings as raw
39: * binary rather than UTF-8, ISO-8859-1, etc
40: *
41: * @param string $binary_string
42: *
43: * @throws TypeError
44: *
45: * @return int
46: */
47: function RandomCompat_strlen($binary_string)
48: {
49: if (!is_string($binary_string)) {
50: throw new TypeError(
51: 'RandomCompat_strlen() expects a string'
52: );
53: }
54:
55: return (int) mb_strlen($binary_string, '8bit');
56: }
57:
58: } else {
59: /**
60: * strlen() implementation that isn't brittle to mbstring.func_overload
61: *
62: * This version just used the default strlen()
63: *
64: * @param string $binary_string
65: *
66: * @throws TypeError
67: *
68: * @return int
69: */
70: function RandomCompat_strlen($binary_string)
71: {
72: if (!is_string($binary_string)) {
73: throw new TypeError(
74: 'RandomCompat_strlen() expects a string'
75: );
76: }
77: return (int) strlen($binary_string);
78: }
79: }
80: }
81:
82: if (!is_callable('RandomCompat_substr')) {
83:
84: if (
85: defined('MB_OVERLOAD_STRING')
86: &&
87: ((int) ini_get('mbstring.func_overload')) & MB_OVERLOAD_STRING
88: ) {
89: /**
90: * substr() implementation that isn't brittle to mbstring.func_overload
91: *
92: * This version uses mb_substr() in '8bit' mode to treat strings as raw
93: * binary rather than UTF-8, ISO-8859-1, etc
94: *
95: * @param string $binary_string
96: * @param int $start
97: * @param int|null $length (optional)
98: *
99: * @throws TypeError
100: *
101: * @return string
102: */
103: function RandomCompat_substr($binary_string, $start, $length = null)
104: {
105: if (!is_string($binary_string)) {
106: throw new TypeError(
107: 'RandomCompat_substr(): First argument should be a string'
108: );
109: }
110:
111: if (!is_int($start)) {
112: throw new TypeError(
113: 'RandomCompat_substr(): Second argument should be an integer'
114: );
115: }
116:
117: if ($length === null) {
118: /**
119: * mb_substr($str, 0, NULL, '8bit') returns an empty string on
120: * PHP 5.3, so we have to find the length ourselves.
121: */
122: /** @var int $length */
123: $length = RandomCompat_strlen($binary_string) - $start;
124: } elseif (!is_int($length)) {
125: throw new TypeError(
126: 'RandomCompat_substr(): Third argument should be an integer, or omitted'
127: );
128: }
129:
130: // Consistency with PHP's behavior
131: if ($start === RandomCompat_strlen($binary_string) && $length === 0) {
132: return '';
133: }
134: if ($start > RandomCompat_strlen($binary_string)) {
135: return '';
136: }
137:
138: return (string) mb_substr(
139: (string) $binary_string,
140: (int) $start,
141: (int) $length,
142: '8bit'
143: );
144: }
145:
146: } else {
147:
148: /**
149: * substr() implementation that isn't brittle to mbstring.func_overload
150: *
151: * This version just uses the default substr()
152: *
153: * @param string $binary_string
154: * @param int $start
155: * @param int|null $length (optional)
156: *
157: * @throws TypeError
158: *
159: * @return string
160: */
161: function RandomCompat_substr($binary_string, $start, $length = null)
162: {
163: if (!is_string($binary_string)) {
164: throw new TypeError(
165: 'RandomCompat_substr(): First argument should be a string'
166: );
167: }
168:
169: if (!is_int($start)) {
170: throw new TypeError(
171: 'RandomCompat_substr(): Second argument should be an integer'
172: );
173: }
174:
175: if ($length !== null) {
176: if (!is_int($length)) {
177: throw new TypeError(
178: 'RandomCompat_substr(): Third argument should be an integer, or omitted'
179: );
180: }
181:
182: return (string) substr(
183: (string )$binary_string,
184: (int) $start,
185: (int) $length
186: );
187: }
188:
189: return (string) substr(
190: (string) $binary_string,
191: (int) $start
192: );
193: }
194: }
195: }
196: