imap_utf7_local.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. <?php
  2. /**
  3. * functions/imap_utf7_local.php - utf7-imap functions
  4. *
  5. * Copyright (c) 1999-2005 The SquirrelMail Project Team
  6. * Licensed under the GNU GPL. For full terms see the file COPYING.
  7. *
  8. * This implements all functions that do imap UTF7 conversions.
  9. * Before 1.3.2 functions were stored in imap_utf7_decode_local.php and
  10. * imap_utf7_encode_local.php files.
  11. *
  12. * @version $Id$
  13. * @package squirrelmail
  14. * @subpackage imap
  15. * @since 1.3.2
  16. */
  17. /**
  18. * Function that uses php mbstring functions to convert from and to utf7-imap charset
  19. *
  20. * Since 1.5.1 list of supported charsets depends sq_mb_list_encoding function.
  21. * Before that it was hardcoded to iso-8859-x, utf-8 and iso-2022-jp.
  22. * @param string $str folder name
  23. * @param string $to_encoding name of resulting charset
  24. * @param string $from_encoding name of original charset
  25. * @param string $default_charset default charset used by translation.
  26. * @return string encoded folder name or ''
  27. * @since 1.4.2
  28. */
  29. function sqimap_mb_convert_encoding($str, $to_encoding, $from_encoding, $default_charset) {
  30. $supported_encodings=sq_mb_list_encodings();
  31. if ( in_array(strtolower($default_charset),$supported_encodings) &&
  32. function_exists('mb_convert_encoding')) {
  33. return mb_convert_encoding($str, $to_encoding, $from_encoding);
  34. }
  35. return '';
  36. }
  37. /**
  38. * encode folder name to utf7-imap
  39. *
  40. * If mbstring functions do not support charset used by translation, falls back to iso-8859-1
  41. * @param string $s folder name
  42. * @return string utf7-imap encoded folder name
  43. * @since 1.2.7
  44. */
  45. function imap_utf7_encode_local($s) {
  46. global $languages, $squirrelmail_language;
  47. if (isset($languages[$squirrelmail_language]['XTRA_CODE']) &&
  48. function_exists($languages[$squirrelmail_language]['XTRA_CODE'].'_utf7_imap_encode')) {
  49. return call_user_func($languages[$squirrelmail_language]['XTRA_CODE'] . '_utf7_imap_encode', $s);
  50. }
  51. if ($s == '') //If empty, don't bother
  52. return '';
  53. global $default_charset;
  54. set_my_charset(); //must be called before using $default_charset
  55. if ((strtolower($default_charset) != 'iso-8859-1') && ($default_charset != '')) {
  56. $utf7_s = sqimap_mb_convert_encoding($s, 'UTF7-IMAP', $default_charset, $default_charset);
  57. if ($utf7_s != '')
  58. return $utf7_s;
  59. }
  60. // Later code works only for ISO-8859-1
  61. $b64_s = ''; // buffer for substring to be base64-encoded
  62. $utf7_s = ''; // imap-utf7-encoded string
  63. for ($i = 0; $i < strlen($s); $i++) {
  64. $c = $s[$i];
  65. $ord_c = ord($c);
  66. if ((($ord_c >= 0x20) and ($ord_c <= 0x25)) or
  67. (($ord_c >= 0x27) and ($ord_c <= 0x7e))) {
  68. if ($b64_s) {
  69. $utf7_s = $utf7_s . '&' . encodeBASE64($b64_s) .'-';
  70. $b64_s = '';
  71. }
  72. $utf7_s = $utf7_s . $c;
  73. } elseif ($ord_c == 0x26) {
  74. if ($b64_s) {
  75. $utf7_s = $utf7_s . '&' . encodeBASE64($b64_s) . '-';
  76. $b64_s = '';
  77. }
  78. $utf7_s = $utf7_s . '&-';
  79. } else {
  80. $b64_s = $b64_s . chr(0) . $c;
  81. }
  82. }
  83. //
  84. // flush buffer
  85. //
  86. if ($b64_s) {
  87. $utf7_s = $utf7_s . '&' . encodeBASE64($b64_s) . '-';
  88. $b64_s = '';
  89. }
  90. return $utf7_s;
  91. }
  92. /**
  93. * converts folder name from utf7-imap to charset used by translation
  94. *
  95. * If mbstring functions do not support charset used by translation, falls back to iso-8859-1
  96. * @param string $s folder name in utf7-imap
  97. * @return string folder name in charset used by translation
  98. * @since 1.2.7
  99. */
  100. function imap_utf7_decode_local($s) {
  101. global $languages, $squirrelmail_language;
  102. if (isset($languages[$squirrelmail_language]['XTRA_CODE']) &&
  103. function_exists($languages[$squirrelmail_language]['XTRA_CODE'] . '_utf7_imap_decode')) {
  104. return call_user_func($languages[$squirrelmail_language]['XTRA_CODE'] . '_utf7_imap_decode', $s);
  105. }
  106. if ($s == '') //If empty, don't bother
  107. return '';
  108. global $default_charset;
  109. set_my_charset(); //must be called before using $default_charset
  110. if ((strtolower($default_charset) != 'iso-8859-1') && ($default_charset != '')) {
  111. $utf7_s = sqimap_mb_convert_encoding($s, $default_charset, 'UTF7-IMAP', $default_charset);
  112. if ($utf7_s != '')
  113. return $utf7_s;
  114. }
  115. // Later code works only for ISO-8859-1
  116. $b64_s = '';
  117. $iso_8859_1_s = '';
  118. for ($i = 0, $len = strlen($s); $i < $len; $i++) {
  119. $c = $s[$i];
  120. if (strlen($b64_s) > 0) {
  121. if ($c == '-') {
  122. if ($b64_s == '&') {
  123. $iso_8859_1_s = $iso_8859_1_s . '&';
  124. } else {
  125. $iso_8859_1_s = $iso_8859_1_s .
  126. decodeBASE64(substr($b64_s, 1));
  127. }
  128. $b64_s = '';
  129. } else {
  130. $b64_s = $b64_s . $c;
  131. }
  132. } else {
  133. if ($c == '&') {
  134. $b64_s = '&';
  135. } else {
  136. $iso_8859_1_s = $iso_8859_1_s . $c;
  137. }
  138. }
  139. }
  140. return $iso_8859_1_s;
  141. }
  142. /**
  143. * Converts string to base64
  144. * @param string $s string
  145. * @return string base64 encoded string
  146. * @since 1.2.7
  147. */
  148. function encodeBASE64($s) {
  149. $B64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+,';
  150. $p = 0; // phase: 1 / 2 / 3 / 1 / 2 / 3...
  151. $e = ''; // base64-encoded string
  152. //foreach($s as $c) {
  153. for ($i = 0; $i < strlen($s); $i++) {
  154. $c = $s[$i];
  155. if ($p == 0) {
  156. $e = $e . substr($B64Chars, ((ord($c) & 252) >> 2), 1);
  157. $t = (ord($c) & 3);
  158. $p = 1;
  159. } elseif ($p == 1) {
  160. $e = $e . $B64Chars[($t << 4) + ((ord($c) & 240) >> 4)];
  161. $t = (ord($c) & 15);
  162. $p = 2;
  163. } elseif ($p == 2) {
  164. $e = $e . $B64Chars[($t << 2) + ((ord($c) & 192) >> 6)];
  165. $e = $e . $B64Chars[ord($c) & 63];
  166. $p = 0;
  167. }
  168. }
  169. //
  170. // flush buffer
  171. //
  172. if ($p == 1) {
  173. $e = $e . $B64Chars[$t << 4];
  174. } elseif ($p == 2) {
  175. $e = $e . $B64Chars[$t << 2];
  176. }
  177. return $e;
  178. }
  179. /**
  180. * Converts string from base64
  181. * @param string $s base64 encoded string
  182. * @return string decoded string
  183. * @since 1.2.7
  184. */
  185. function decodeBASE64($s) {
  186. $B64Values = array(
  187. 'A' => 0, 'B' => 1, 'C' => 2, 'D' => 3, 'E' => 4, 'F' => 5,
  188. 'G' => 6, 'H' => 7, 'I' => 8, 'J' => 9, 'K' => 10, 'L' => 11,
  189. 'M' => 12, 'N' => 13, 'O' => 14, 'P' => 15, 'Q' => 16, 'R' => 17,
  190. 'S' => 18, 'T' => 19, 'U' => 20, 'V' => 21, 'W' => 22, 'X' => 23,
  191. 'Y' => 24, 'Z' => 25,
  192. 'a' => 26, 'b' => 27, 'c' => 28, 'd' => 29, 'e' => 30, 'f' => 31,
  193. 'g' => 32, 'h' => 33, 'i' => 34, 'j' => 35, 'k' => 36, 'l' => 37,
  194. 'm' => 38, 'n' => 39, 'o' => 40, 'p' => 41, 'q' => 42, 'r' => 43,
  195. 's' => 44, 't' => 45, 'u' => 46, 'v' => 47, 'w' => 48, 'x' => 49,
  196. 'y' => 50, 'z' => 51,
  197. '0' => 52, '1' => 53, '2' => 54, '3' => 55, '4' => 56, '5' => 57,
  198. '6' => 58, '7' => 59, '8' => 60, '9' => 61, '+' => 62, ',' => 63
  199. );
  200. $p = 0;
  201. $d = '';
  202. $unicodeNullByteToggle = 0;
  203. for ($i = 0, $len = strlen($s); $i < $len; $i++) {
  204. $c = $s[$i];
  205. if ($p == 0) {
  206. $t = $B64Values[$c];
  207. $p = 1;
  208. } elseif ($p == 1) {
  209. if ($unicodeNullByteToggle) {
  210. $d = $d . chr(($t << 2) + (($B64Values[$c] & 48) >> 4));
  211. $unicodeNullByteToggle = 0;
  212. } else {
  213. $unicodeNullByteToggle = 1;
  214. }
  215. $t = ($B64Values[$c] & 15);
  216. $p = 2;
  217. } elseif ($p == 2) {
  218. if ($unicodeNullByteToggle) {
  219. $d = $d . chr(($t << 4) + (($B64Values[$c] & 60) >> 2));
  220. $unicodeNullByteToggle = 0;
  221. } else {
  222. $unicodeNullByteToggle = 1;
  223. }
  224. $t = ($B64Values[$c] & 3);
  225. $p = 3;
  226. } elseif ($p == 3) {
  227. if ($unicodeNullByteToggle) {
  228. $d = $d . chr(($t << 6) + $B64Values[$c]);
  229. $unicodeNullByteToggle = 0;
  230. } else {
  231. $unicodeNullByteToggle = 1;
  232. }
  233. $t = ($B64Values[$c] & 3);
  234. $p = 0;
  235. }
  236. }
  237. return $d;
  238. }
  239. ?>