byte_safe_strings.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  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. if (!is_callable('RandomCompat_strlen')) {
  29. if (
  30. defined('MB_OVERLOAD_STRING')
  31. &&
  32. ((int) ini_get('mbstring.func_overload')) & MB_OVERLOAD_STRING
  33. ) {
  34. /**
  35. * strlen() implementation that isn't brittle to mbstring.func_overload
  36. *
  37. * This version uses mb_strlen() in '8bit' mode to treat strings as raw
  38. * binary rather than UTF-8, ISO-8859-1, etc
  39. *
  40. * @param string $binary_string
  41. *
  42. * @throws TypeError
  43. *
  44. * @return int
  45. */
  46. function RandomCompat_strlen($binary_string)
  47. {
  48. if (!is_string($binary_string)) {
  49. throw new TypeError(
  50. 'RandomCompat_strlen() expects a string'
  51. );
  52. }
  53. return (int) mb_strlen($binary_string, '8bit');
  54. }
  55. } else {
  56. /**
  57. * strlen() implementation that isn't brittle to mbstring.func_overload
  58. *
  59. * This version just used the default strlen()
  60. *
  61. * @param string $binary_string
  62. *
  63. * @throws TypeError
  64. *
  65. * @return int
  66. */
  67. function RandomCompat_strlen($binary_string)
  68. {
  69. if (!is_string($binary_string)) {
  70. throw new TypeError(
  71. 'RandomCompat_strlen() expects a string'
  72. );
  73. }
  74. return (int) strlen($binary_string);
  75. }
  76. }
  77. }
  78. if (!is_callable('RandomCompat_substr')) {
  79. if (
  80. defined('MB_OVERLOAD_STRING')
  81. &&
  82. ((int) ini_get('mbstring.func_overload')) & MB_OVERLOAD_STRING
  83. ) {
  84. /**
  85. * substr() implementation that isn't brittle to mbstring.func_overload
  86. *
  87. * This version uses mb_substr() in '8bit' mode to treat strings as raw
  88. * binary rather than UTF-8, ISO-8859-1, etc
  89. *
  90. * @param string $binary_string
  91. * @param int $start
  92. * @param int|null $length (optional)
  93. *
  94. * @throws TypeError
  95. *
  96. * @return string
  97. */
  98. function RandomCompat_substr($binary_string, $start, $length = null)
  99. {
  100. if (!is_string($binary_string)) {
  101. throw new TypeError(
  102. 'RandomCompat_substr(): First argument should be a string'
  103. );
  104. }
  105. if (!is_int($start)) {
  106. throw new TypeError(
  107. 'RandomCompat_substr(): Second argument should be an integer'
  108. );
  109. }
  110. if ($length === null) {
  111. /**
  112. * mb_substr($str, 0, NULL, '8bit') returns an empty string on
  113. * PHP 5.3, so we have to find the length ourselves.
  114. */
  115. /** @var int $length */
  116. $length = RandomCompat_strlen($binary_string) - $start;
  117. } elseif (!is_int($length)) {
  118. throw new TypeError(
  119. 'RandomCompat_substr(): Third argument should be an integer, or omitted'
  120. );
  121. }
  122. // Consistency with PHP's behavior
  123. if ($start === RandomCompat_strlen($binary_string) && $length === 0) {
  124. return '';
  125. }
  126. if ($start > RandomCompat_strlen($binary_string)) {
  127. return '';
  128. }
  129. return (string) mb_substr(
  130. (string) $binary_string,
  131. (int) $start,
  132. (int) $length,
  133. '8bit'
  134. );
  135. }
  136. } else {
  137. /**
  138. * substr() implementation that isn't brittle to mbstring.func_overload
  139. *
  140. * This version just uses the default substr()
  141. *
  142. * @param string $binary_string
  143. * @param int $start
  144. * @param int|null $length (optional)
  145. *
  146. * @throws TypeError
  147. *
  148. * @return string
  149. */
  150. function RandomCompat_substr($binary_string, $start, $length = null)
  151. {
  152. if (!is_string($binary_string)) {
  153. throw new TypeError(
  154. 'RandomCompat_substr(): First argument should be a string'
  155. );
  156. }
  157. if (!is_int($start)) {
  158. throw new TypeError(
  159. 'RandomCompat_substr(): Second argument should be an integer'
  160. );
  161. }
  162. if ($length !== null) {
  163. if (!is_int($length)) {
  164. throw new TypeError(
  165. 'RandomCompat_substr(): Third argument should be an integer, or omitted'
  166. );
  167. }
  168. return (string) substr(
  169. (string )$binary_string,
  170. (int) $start,
  171. (int) $length
  172. );
  173. }
  174. return (string) substr(
  175. (string) $binary_string,
  176. (int) $start
  177. );
  178. }
  179. }
  180. }