PageRenderTime 49ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/wp-content/plugins/s2member/includes/classes/utils-strings.inc.php

https://gitlab.com/Gashler/dp
PHP | 548 lines | 247 code | 23 blank | 278 comment | 39 complexity | a5b921668fb43e04264959f7b5b90a00 MD5 | raw file
  1. <?php
  2. /**
  3. * String utilities.
  4. *
  5. * Copyright: © 2009-2011
  6. * {@link http://www.websharks-inc.com/ WebSharks, Inc.}
  7. * (coded in the USA)
  8. *
  9. * Released under the terms of the GNU General Public License.
  10. * You should have received a copy of the GNU General Public License,
  11. * along with this software. In the main directory, see: /licensing/
  12. * If not, see: {@link http://www.gnu.org/licenses/}.
  13. *
  14. * @package s2Member\Utilities
  15. * @since 3.5
  16. */
  17. if(realpath(__FILE__) === realpath($_SERVER["SCRIPT_FILENAME"]))
  18. exit("Do not access this file directly.");
  19. if(!class_exists("c_ws_plugin__s2member_utils_strings"))
  20. {
  21. /**
  22. * String utilities.
  23. *
  24. * @package s2Member\Utilities
  25. * @since 3.5
  26. */
  27. class c_ws_plugin__s2member_utils_strings
  28. {
  29. /**
  30. * Array of all ampersand entities.
  31. *
  32. * Array keys are actually regex patterns *(very useful)*.
  33. *
  34. * @package s2Member\Utilities
  35. * @since 111106
  36. *
  37. * @var array
  38. */
  39. public static $ampersand_entities = array("&amp;" => "&amp;", "&#0*38;" => "&#38;", "&#[xX]0*26;" => "&#x26;");
  40. /**
  41. * Array of all quote entities *(and entities for quote variations)*.
  42. *
  43. * Array keys are actually regex patterns *(very useful)*.
  44. *
  45. * @package s2Member\Utilities
  46. * @since 111106
  47. *
  48. * @var array
  49. */
  50. public static $quote_entities_w_variations = array("&apos;" => "&apos;", "&#0*39;" => "&#39;", "&#[xX]0*27;" => "&#x27;", "&lsquo;" => "&lsquo;", "&#0*8216;" => "&#8216;", "&#[xX]0*2018;" => "&#x2018;", "&rsquo;" => "&rsquo;", "&#0*8217;" => "&#8217;", "&#[xX]0*2019;" => "&#x2019;", "&quot;" => "&quot;", "&#0*34;" => "&#34;", "&#[xX]0*22;" => "&#x22;", "&ldquo;" => "&ldquo;", "&#0*8220;" => "&#8220;", "&#[xX]0*201[cC];" => "&#x201C;", "&rdquo;" => "&rdquo;", "&#0*8221;" => "&#8221;", "&#[xX]0*201[dD];" => "&#x201D;");
  51. /**
  52. * Escapes double quotes.
  53. *
  54. * @package s2Member\Utilities
  55. * @since 3.5
  56. *
  57. * @param str $string Input string.
  58. * @param int $times Number of escapes. Defaults to 1.
  59. * @param str $escape_char The character to be used in escapes.
  60. * @return str Output string after double quotes are escaped.
  61. */
  62. public static function esc_dq($string = FALSE, $times = FALSE, $escape_char = "\\")
  63. {
  64. $times = (is_numeric($times) && $times >= 0) ? (int)$times : 1;
  65. return str_replace('"', str_repeat($escape_char, $times).'"', (string)$string);
  66. }
  67. /**
  68. * Escapes single quotes.
  69. *
  70. * @package s2Member\Utilities
  71. * @since 3.5
  72. *
  73. * @param str $string Input string.
  74. * @param int $times Number of escapes. Defaults to 1.
  75. * @return str Output string after single quotes are escaped.
  76. */
  77. public static function esc_sq($string = FALSE, $times = FALSE)
  78. {
  79. $times = (is_numeric($times) && $times >= 0) ? (int)$times : 1;
  80. return str_replace("'", str_repeat("\\", $times)."'", (string)$string);
  81. }
  82. /**
  83. * Escapes JavaScript and single quotes.
  84. *
  85. * @package s2Member\Utilities
  86. * @since 110901
  87. *
  88. * @param str $string Input string.
  89. * @param int $times Number of escapes. Defaults to 1.
  90. * @return str Output string after JavaScript and single quotes are escaped.
  91. */
  92. public static function esc_js_sq($string = FALSE, $times = FALSE)
  93. {
  94. $times = (is_numeric($times) && $times >= 0) ? (int)$times : 1;
  95. return str_replace("'", str_repeat("\\", $times)."'", str_replace(array("\r", "\n"), array("", '\\n'), str_replace("\'", "'", (string)$string)));
  96. }
  97. /**
  98. * Escapes dollars signs (for regex patterns).
  99. *
  100. * @package s2Member\Utilities
  101. * @since 3.5
  102. *
  103. * @param str $string Input string.
  104. * @param int $times Number of escapes. Defaults to 1.
  105. * @return str Output string after dollar signs are escaped.
  106. *
  107. * @deprecated Starting with s2Member v120103, please use:
  108. * ``c_ws_plugin__s2member_utils_strings::esc_refs()``.
  109. */
  110. public static function esc_ds($string = FALSE, $times = FALSE)
  111. {
  112. $times = (is_numeric($times) && $times >= 0) ? (int)$times : 1;
  113. return str_replace('$', str_repeat("\\", $times).'$', (string)$string);
  114. }
  115. /**
  116. * Escapes backreferences (for regex patterns).
  117. *
  118. * @package s2Member\Utilities
  119. * @since 120103
  120. *
  121. * @param str $string Input string.
  122. * @param int $times Number of escapes. Defaults to 1.
  123. * @return str Output string after backreferences are escaped.
  124. */
  125. public static function esc_refs($string = NULL, $times = NULL)
  126. {
  127. $times = (is_numeric($times) && $times >= 0) ? (int)$times : 1;
  128. return str_replace(array("\\", '$'), array(str_repeat("\\", $times)."\\", str_repeat("\\", $times).'$'), (string)$string);
  129. }
  130. /**
  131. * Sanitizes a string; by stripping characters NOT on a standard U.S. keyboard.
  132. *
  133. * @package s2Member\Utilities
  134. * @since 111106
  135. *
  136. * @param str $string Input string.
  137. * @return str Output string, after characters NOT on a standard U.S. keyboard have been stripped.
  138. */
  139. public static function strip_2_kb_chars($string = FALSE)
  140. {
  141. return preg_replace("/[^0-9A-Z\r\n\t\s`\=\[\]\\\;',\.\/~\!@#\$%\^&\*\(\)_\+\|\}\{\:\"\?\>\<\-]/i", "", remove_accents((string)$string));
  142. }
  143. /**
  144. * Trims deeply; alias of ``trim_deep``.
  145. *
  146. * @package s2Member\Utilities
  147. * @since 111106
  148. *
  149. * @see s2Member\Utilities\c_ws_plugin__s2member_utils_strings::trim_deep()
  150. * @see http://php.net/manual/en/function.trim.php
  151. *
  152. * @param str|array $value Either a string, an array, or a multi-dimensional array, filled with integer and/or string values.
  153. * @param str|bool $chars Optional. Defaults to false, indicating the default trim chars ` \t\n\r\0\x0B`. Or, set to a specific string of chars.
  154. * @param str|bool $extra_chars Optional. This is NOT possible with PHP alone, but here you can specify extra chars; in addition to ``$chars``.
  155. * @return str|array Either the input string, or the input array; after all data is trimmed up according to arguments passed in.
  156. */
  157. public static function trim($value = FALSE, $chars = FALSE, $extra_chars = FALSE)
  158. {
  159. return c_ws_plugin__s2member_utils_strings::trim_deep($value, $chars, $extra_chars);
  160. }
  161. /**
  162. * Trims deeply; or use {@link s2Member\Utilities\c_ws_plugin__s2member_utils_strings::trim()}.
  163. *
  164. * @package s2Member\Utilities
  165. * @since 3.5
  166. *
  167. * @see s2Member\Utilities\c_ws_plugin__s2member_utils_strings::trim()
  168. * @see http://php.net/manual/en/function.trim.php
  169. *
  170. * @param str|array $value Either a string, an array, or a multi-dimensional array, filled with integer and/or string values.
  171. * @param str|bool $chars Optional. Defaults to false, indicating the default trim chars ` \t\n\r\0\x0B`. Or, set to a specific string of chars.
  172. * @param str|bool $extra_chars Optional. This is NOT possible with PHP alone, but here you can specify extra chars; in addition to ``$chars``.
  173. * @return str|array Either the input string, or the input array; after all data is trimmed up according to arguments passed in.
  174. */
  175. public static function trim_deep($value = FALSE, $chars = FALSE, $extra_chars = FALSE)
  176. {
  177. $chars = /* List of chars to be trimmed by this routine. */ (is_string($chars)) ? $chars : " \t\n\r\0\x0B";
  178. $chars = (is_string($extra_chars) /* Adding additional chars? */) ? $chars.$extra_chars : $chars;
  179. if(is_array($value)) /* Handles all types of arrays.
  180. Note, we do NOT use ``array_map()`` here, because multiple args to ``array_map()`` causes a loss of string keys.
  181. For further details, see: <http://php.net/manual/en/function.array-map.php>. */
  182. {
  183. foreach($value as &$r) // Reference.
  184. $r = c_ws_plugin__s2member_utils_strings::trim_deep($r, $chars);
  185. return $value; // Return modified array.
  186. }
  187. return trim((string)$value, $chars);
  188. }
  189. /**
  190. * Trims double quotes deeply.
  191. *
  192. * @package s2Member\Utilities
  193. * @since 3.5
  194. *
  195. * @param str|array $value Either a string, an array, or a multi-dimensional array, filled with integer and/or string values.
  196. * @return str|array Either the input string, or the input array; after all data is trimmed up.
  197. */
  198. public static function trim_dq_deep($value = FALSE)
  199. {
  200. return c_ws_plugin__s2member_utils_strings::trim_deep($value, false, '"');
  201. }
  202. /**
  203. * Trims single quotes deeply.
  204. *
  205. * @package s2Member\Utilities
  206. * @since 111106
  207. *
  208. * @param str|array $value Either a string, an array, or a multi-dimensional array, filled with integer and/or string values.
  209. * @return str|array Either the input string, or the input array; after all data is trimmed up.
  210. */
  211. public static function trim_sq_deep($value = FALSE)
  212. {
  213. return c_ws_plugin__s2member_utils_strings::trim_deep($value, false, "'");
  214. }
  215. /**
  216. * Trims double and single quotes deeply.
  217. *
  218. * @package s2Member\Utilities
  219. * @since 111106
  220. *
  221. * @param str|array $value Either a string, an array, or a multi-dimensional array, filled with integer and/or string values.
  222. * @return str|array Either the input string, or the input array; after all data is trimmed up.
  223. */
  224. public static function trim_dsq_deep($value = FALSE)
  225. {
  226. return c_ws_plugin__s2member_utils_strings::trim_deep($value, false, "'".'"');
  227. }
  228. /**
  229. * Trims all single/double quote entity variations deeply.
  230. *
  231. * This is useful on Shortcode attributes mangled by a Visual Editor.
  232. *
  233. * @package s2Member\Utilities
  234. * @since 111011
  235. *
  236. * @param str|array $value Either a string, an array, or a multi-dimensional array, filled with integer and/or string values.
  237. * @return str|array Either the input string, or the input array; after all data is trimmed up.
  238. */
  239. public static function trim_qts_deep($value = FALSE)
  240. {
  241. $qts = implode("|", array_keys /* Keys are regex patterns. */(c_ws_plugin__s2member_utils_strings::$quote_entities_w_variations));
  242. return is_array($value) ? array_map("c_ws_plugin__s2member_utils_strings::trim_qts_deep", $value) : preg_replace("/^(?:".$qts.")+|(?:".$qts.")+$/", "", (string)$value);
  243. }
  244. /**
  245. * Wraps a string with the characters provided.
  246. *
  247. * This is useful when preparing an input array for ``c_ws_plugin__s2member_utils_arrays::in_regex_array()``.
  248. *
  249. * @package s2Member\Utilities
  250. * @since 3.5
  251. *
  252. * @param str|array $value Either a string, an array, or a multi-dimensional array, filled with integer and/or string values.
  253. * @param str $beg Optional. A string value to wrap at the beginning of each value.
  254. * @param str $end Optional. A string value to wrap at the ending of each value.
  255. * @param bool $wrap_e Optional. Defaults to false. Should empty strings be wrapped too?
  256. * @return str|array Either the input string, or the input array; after all data is wrapped up.
  257. */
  258. public static function wrap_deep($value = FALSE, $beg = FALSE, $end = FALSE, $wrap_e = FALSE)
  259. {
  260. if(is_array($value)) /* Handles all types of arrays.
  261. Note, we do NOT use ``array_map()`` here, because multiple args to ``array_map()`` causes a loss of string keys.
  262. For further details, see: <http://php.net/manual/en/function.array-map.php>. */
  263. {
  264. foreach($value as &$r) // Reference.
  265. $r = c_ws_plugin__s2member_utils_strings::wrap_deep($r, $beg, $end, $wrap_e);
  266. return $value; // Return modified array.
  267. }
  268. return (strlen((string)$value) || $wrap_e) ? (string)$beg.(string)$value.(string)$end : (string)$value;
  269. }
  270. /**
  271. * Escapes meta characters with ``preg_quote()`` deeply.
  272. *
  273. * @package s2Member\Utilities
  274. * @since 110926
  275. *
  276. * @param str|array $value Either a string, an array, or a multi-dimensional array, filled with integer and/or string values.
  277. * @param str $delimiter Optional. If a delimiting character is specified, it will also be escaped via ``preg_quote()``.
  278. * @return str|array Either the input string, or the input array; after all data is escaped with ``preg_quote()``.
  279. */
  280. public static function preg_quote_deep($value = FALSE, $delimiter = FALSE)
  281. {
  282. if(is_array($value)) /* Handles all types of arrays.
  283. Note, we do NOT use ``array_map()`` here, because multiple args to ``array_map()`` causes a loss of string keys.
  284. For further details, see: <http://php.net/manual/en/function.array-map.php>. */
  285. {
  286. foreach($value as &$r) // Reference.
  287. $r = c_ws_plugin__s2member_utils_strings::preg_quote_deep($r, $delimiter);
  288. return $value; // Return modified array.
  289. }
  290. return preg_quote((string)$value, (string)$delimiter);
  291. }
  292. /**
  293. * Generates a random string with letters/numbers/symbols.
  294. *
  295. * @package s2Member\Utilities
  296. * @since 3.5
  297. *
  298. * @param int $length Optional. Defaults to `12`. Length of the random string.
  299. * @param bool $special_chars Defaults to true. If false, special chars are NOT included.
  300. * @param bool $extra_special_chars Defaults to false. If true, extra special chars are included.
  301. * @return str A randomly generated string, based on parameter configuration.
  302. */
  303. public static function random_str_gen($length = FALSE, $special_chars = TRUE, $extra_special_chars = FALSE)
  304. {
  305. $length = (is_numeric($length) && $length >= 0) ? (int)$length : 12;
  306. $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  307. $chars .= ($extra_special_chars) ? "-_ []{}<>~`+=,.;:/?|" : "";
  308. $chars .= ($special_chars) ? "!@#$%^&*()" : "";
  309. for($i = 0, $random_str = ""; $i < $length; $i++)
  310. $random_str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
  311. return /* Randomly generated string of chars. */ $random_str;
  312. }
  313. /**
  314. * Highlights PHP, and also Shortcodes.
  315. *
  316. * @package s2Member\Utilities
  317. * @since 3.5
  318. *
  319. * @param str $str Input string to be highlighted.
  320. * @return str The highlighted string.
  321. */
  322. public static function highlight_php($string = FALSE)
  323. {
  324. $string = highlight_string((string)$string, true); // Start with PHP syntax, then Shortcodes.
  325. return preg_replace("/\[\/?_*s2[a-z0-9_\-]+.*?\]/i", '<span style="color:#164A61;">$0</span>', $string);
  326. }
  327. /**
  328. * Parses email addresses from a string or array.
  329. *
  330. * @package s2Member\Utilities
  331. * @since 111009
  332. *
  333. * @param str|array $value Input string or an array is also fine.
  334. * @return array Array of parsed email addresses.
  335. */
  336. public static function parse_emails($value = FALSE)
  337. {
  338. if(is_array($value)) /* Handles all types of arrays.
  339. Note, we do NOT use ``array_map()`` here, because multiple args to ``array_map()`` causes a loss of string keys.
  340. For further details, see: <http://php.net/manual/en/function.array-map.php>. */
  341. {
  342. $emails = array(); // Initialize array.
  343. foreach /* Loop through array. */($value as $v)
  344. $emails = array_merge($emails, c_ws_plugin__s2member_utils_strings::parse_emails($v));
  345. return $emails; // Return array.
  346. }
  347. $delimiter = /* Supports semicolons or commas. */ (strpos((string)$value, ";") !== false) ? ";" : ",";
  348. foreach(c_ws_plugin__s2member_utils_strings::trim_deep(preg_split("/".preg_quote($delimiter, "/")."+/", (string)$value)) as $section)
  349. {
  350. if(preg_match("/\<(.+?)\>/", $section, $m) && strpos($m[1], "@") !== false)
  351. $emails[] = $m[1]; // Email inside <brackets>.
  352. else if(strpos($section, "@") !== false)
  353. $emails[] = $section;
  354. }
  355. return /* Array. */ (!empty($emails)) ? $emails : array();
  356. }
  357. /**
  358. * Base64 URL-safe encoding.
  359. *
  360. * @package s2Member\Utilities
  361. * @since 110913
  362. *
  363. * @param str $string Input string to be base64 encoded.
  364. * @param array $url_unsafe_chars Optional. An array of un-safe characters. Defaults to: ``array("+", "/")``.
  365. * @param array $url_safe_chars Optional. An array of safe character replacements. Defaults to: ``array("-", "_")``.
  366. * @param str $trim_padding_chars Optional. A string of padding chars to rtrim. Defaults to: `=~.`.
  367. * @return str The base64 URL-safe encoded string.
  368. */
  369. public static function base64_url_safe_encode($string = FALSE, $url_unsafe_chars = array("+", "/"), $url_safe_chars = array("-", "_"), $trim_padding_chars = "=~.")
  370. {
  371. $string = (string)$string; // Force string values here. String MUST be a string.
  372. $trim_padding_chars = (string)$trim_padding_chars; // And force this one too.
  373. $base64_url_safe = str_replace((array)$url_unsafe_chars, (array)$url_safe_chars, (string)base64_encode($string));
  374. $base64_url_safe = (strlen($trim_padding_chars)) ? rtrim($base64_url_safe, $trim_padding_chars) : $base64_url_safe;
  375. return $base64_url_safe; // Base64 encoded, with URL-safe replacements.
  376. }
  377. /**
  378. * Base64 URL-safe decoding.
  379. *
  380. * Note, this function is backward compatible with routines supplied by s2Member in the past;
  381. * where padding characters were replaced with `~` or `.`, instead of being stripped completely.
  382. *
  383. * @package s2Member\Utilities
  384. * @since 110913
  385. *
  386. * @param str $base64_url_safe Input string to be base64 decoded.
  387. * @param array $url_unsafe_chars Optional. An array of un-safe character replacements. Defaults to: ``array("+", "/")``.
  388. * @param array $url_safe_chars Optional. An array of safe characters. Defaults to: ``array("-", "_")``.
  389. * @param str $trim_padding_chars Optional. A string of padding chars to rtrim. Defaults to: `=~.`.
  390. * @return str The decoded string.
  391. */
  392. public static function base64_url_safe_decode($base64_url_safe = FALSE, $url_unsafe_chars = array("+", "/"), $url_safe_chars = array("-", "_"), $trim_padding_chars = "=~.")
  393. {
  394. $base64_url_safe = (string)$base64_url_safe; // Force string values here. This MUST be a string.
  395. $trim_padding_chars = (string)$trim_padding_chars; // And force this one too.
  396. $string = (strlen($trim_padding_chars)) ? rtrim($base64_url_safe, $trim_padding_chars) : $base64_url_safe;
  397. $string = (strlen($trim_padding_chars)) ? str_pad($string, strlen($string) % 4, "=", STR_PAD_RIGHT) : $string;
  398. $string = (string)base64_decode(str_replace((array)$url_safe_chars, (array)$url_unsafe_chars, $string));
  399. return $string; // Base64 decoded, with URL-safe replacements.
  400. }
  401. /**
  402. * Generates an RSA-SHA1 signature.
  403. *
  404. * @package s2Member\Utilities
  405. * @since 111017
  406. *
  407. * @param str $string Input string/data, to be signed by this routine.
  408. * @param str $key The secret key that will be used in this signature.
  409. * @return str|bool An RSA-SHA1 signature string, or false on failure.
  410. */
  411. public static function rsa_sha1_sign($string = FALSE, $key = FALSE)
  412. {
  413. $key = /* Fixes key wrappers. */ c_ws_plugin__s2member_utils_strings::_rsa_sha1_key_fix_wrappers((string)$key);
  414. $signature = /* Command line. */ c_ws_plugin__s2member_utils_strings::_rsa_sha1_shell_sign((string)$string, (string)$key);
  415. if(empty($signature) && stripos(PHP_OS, "win") === 0 && file_exists(($openssl = "c:\openssl-win32\bin\openssl.exe")))
  416. $signature = c_ws_plugin__s2member_utils_strings::_rsa_sha1_shell_sign((string)$string, (string)$key, /* Specific location. */ $openssl);
  417. if(empty($signature) && stripos(PHP_OS, "win") === 0 && file_exists(($openssl = "c:\openssl-win64\bin\openssl.exe")))
  418. $signature = c_ws_plugin__s2member_utils_strings::_rsa_sha1_shell_sign((string)$string, (string)$key, /* Specific location. */ $openssl);
  419. if(empty($signature) && function_exists("openssl_get_privatekey") && function_exists("openssl_sign") && is_resource($private_key = openssl_get_privatekey((string)$key)))
  420. openssl_sign((string)$string, $signature, $private_key, OPENSSL_ALGO_SHA1).openssl_free_key($private_key);
  421. if(empty($signature)) // Now, if we're still empty, trigger an error here.
  422. trigger_error("s2Member was unable to generate an RSA-SHA1 signature.".
  423. " Please make sure your installation of PHP is compiled with OpenSSL: `openssl_sign()`.".
  424. " See: http://php.net/manual/en/function.openssl-sign.php", E_USER_ERROR);
  425. return (!empty($signature)) ? $signature : false;
  426. }
  427. /**
  428. * Generates an RSA-SHA1 signature from the command line.
  429. *
  430. * Used by {@link s2Member\Utilities\c_ws_plugin__s2member_utils_strings::rsa_sha1_sign()}.
  431. *
  432. * @package s2Member\Utilities
  433. * @since 111017
  434. *
  435. * @param str $string Input string/data, to be signed by this routine.
  436. * @param str $key The secret key that will be used in this signature.
  437. * @param str $openssl Optional. Defaults to `openssl`. Path to OpenSSL executable.
  438. * @return str|bool An RSA-SHA1 signature string, or false on failure.
  439. */
  440. public static function _rsa_sha1_shell_sign($string = FALSE, $key = FALSE, $openssl = FALSE)
  441. {
  442. if(function_exists("shell_exec") && ($esa = "escapeshellarg") && ($openssl = (($openssl && is_string($openssl)) ? $openssl : "openssl")) && ($temp_dir = c_ws_plugin__s2member_utils_dirs::get_temp_dir()))
  443. {
  444. file_put_contents(($string_file = $temp_dir."/".md5(uniqid("", true)."rsa-sha1-string").".tmp"), (string)$string);
  445. file_put_contents(($private_key_file = $temp_dir."/".md5(uniqid("", true)."rsa-sha1-private-key").".tmp"), (string)$key);
  446. file_put_contents(($rsa_sha1_sig_file = $temp_dir."/".md5(uniqid("", true)."rsa-sha1-sig").".tmp"), "");
  447. @shell_exec($esa($openssl)." sha1 -sign ".$esa($private_key_file)." -out ".$esa($rsa_sha1_sig_file)." ".$esa($string_file));
  448. $signature = /* Do NOT trim here. */ file_get_contents($rsa_sha1_sig_file); // Was the signature was written?
  449. unlink($rsa_sha1_sig_file).unlink($private_key_file).unlink($string_file); // Cleanup.
  450. }
  451. return (!empty($signature)) ? $signature : false;
  452. }
  453. /**
  454. * Fixes incomplete private key wrappers for RSA-SHA1 signing.
  455. *
  456. * Used by {@link s2Member\Utilities\c_ws_plugin__s2member_utils_strings::rsa_sha1_sign()}.
  457. *
  458. * @package s2Member\Utilities
  459. * @since 111017
  460. *
  461. * @param str $key The secret key to be used in an RSA-SHA1 signature.
  462. * @return str Key with incomplete wrappers corrected, when/if possible.
  463. *
  464. * @see http://www.faqs.org/qa/qa-14736.html
  465. */
  466. public static function _rsa_sha1_key_fix_wrappers($key = FALSE)
  467. {
  468. if(($key = trim((string)$key)) && (strpos($key, "-----BEGIN RSA PRIVATE KEY-----") === false || strpos($key, "-----END RSA PRIVATE KEY-----") === false))
  469. {
  470. foreach(($lines = c_ws_plugin__s2member_utils_strings::trim_deep(preg_split("/[\r\n]+/", $key))) as $line => $value)
  471. if(strpos($value, "-") === 0) // Begins with a boundary identifying character ( a hyphen `-` )?
  472. {
  473. $boundaries = (empty($boundaries)) ? 1 : $boundaries + 1; // Counter.
  474. unset($lines[$line]); // Remove this boundary line. We'll fix these below.
  475. }
  476. if(empty($boundaries) || $boundaries <= 2) // Do NOT modify keys with more than 2 boundaries.
  477. $key = "-----BEGIN RSA PRIVATE KEY-----\n".implode("\n", $lines)."\n-----END RSA PRIVATE KEY-----";
  478. }
  479. return $key; // Always a trimmed string here.
  480. }
  481. /**
  482. * Generates an HMAC-SHA1 signature.
  483. *
  484. * @package s2Member\Utilities
  485. * @since 111017
  486. *
  487. * @param str $string Input string/data, to be signed by this routine.
  488. * @param str $key The secret key that will be used in this signature.
  489. * @return str An HMAC-SHA1 signature string.
  490. */
  491. public static function hmac_sha1_sign($string = FALSE, $key = FALSE)
  492. {
  493. $key_64 = str_pad(((strlen((string)$key) > 64) ? pack('H*', sha1((string)$key)) : (string)$key), 64, chr(0x00));
  494. return pack('H*', sha1(($key_64 ^ str_repeat(chr(0x5c), 64)).pack('H*', sha1(($key_64 ^ str_repeat(chr(0x36), 64)).(string)$string))));
  495. }
  496. /**
  497. * Decodes unreserved chars encoded by PHP's ``urlencode()``, deeply.
  498. *
  499. * For further details regarding unreserved chars, see: {@link http://www.faqs.org/rfcs/rfc3986.html}.
  500. *
  501. * @package s2Member\Utilities
  502. * @since 111017
  503. *
  504. * @see http://www.faqs.org/rfcs/rfc3986.html
  505. *
  506. * @param str|array $value Either a string, an array, or a multi-dimensional array, filled with integer and/or string values.
  507. * @return str|array Either the input string, or the input array; after all unreserved chars are decoded properly.
  508. */
  509. public static function urldecode_ur_chars_deep($value = array())
  510. {
  511. if(is_array($value)) /* Handles all types of arrays.
  512. Note, we do NOT use ``array_map()`` here, because multiple args to ``array_map()`` causes a loss of string keys.
  513. For further details, see: <http://php.net/manual/en/function.array-map.php>. */
  514. {
  515. foreach($value as &$r) // Reference.
  516. $r = c_ws_plugin__s2member_utils_strings::urldecode_ur_chars_deep($r);
  517. return $value; // Return modified array.
  518. }
  519. return str_replace(array("%2D", "%2E", "%5F", "%7E"), array("-", ".", "_", "~"), (string)$value);
  520. }
  521. }
  522. }
  523. ?>