PageRenderTime 55ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 1ms

/php5/ext/mbstring/mbstring.c

http://github.com/vpj/PHP-Extension-API
C | 4894 lines | 3937 code | 551 blank | 406 comment | 1119 complexity | 5d03371e366ee3b8905913514bf2535b MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2009 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Author: Tsukada Takuya <tsukada@fminn.nagano.nagano.jp> |
  16. | Rui Hirokawa <hirokawa@php.net> |
  17. +----------------------------------------------------------------------+
  18. */
  19. /* $Id: mbstring.c,v 1.224.2.22.2.25.2.53 2009/04/20 16:07:59 jani Exp $ */
  20. /*
  21. * PHP 4 Multibyte String module "mbstring"
  22. *
  23. * History:
  24. * 2000.5.19 Release php-4.0RC2_jstring-1.0
  25. * 2001.4.1 Release php4_jstring-1.0.91
  26. * 2001.4.30 Release php4_jstring-1.1 (contribute to The PHP Group)
  27. * 2001.5.1 Renamed from jstring to mbstring (hirokawa@php.net)
  28. */
  29. /*
  30. * PHP3 Internationalization support program.
  31. *
  32. * Copyright (c) 1999,2000 by the PHP3 internationalization team.
  33. * All rights reserved.
  34. *
  35. * See README_PHP3-i18n-ja for more detail.
  36. *
  37. * Authors:
  38. * Hironori Sato <satoh@jpnnet.com>
  39. * Shigeru Kanemoto <sgk@happysize.co.jp>
  40. * Tsukada Takuya <tsukada@fminn.nagano.nagano.jp>
  41. * Rui Hirokawa <rui_hirokawa@ybb.ne.jp>
  42. */
  43. /* {{{ includes */
  44. #ifdef HAVE_CONFIG_H
  45. #include "config.h"
  46. #endif
  47. #include "php.h"
  48. #include "php_ini.h"
  49. #include "php_variables.h"
  50. #include "mbstring.h"
  51. #include "ext/standard/php_string.h"
  52. #include "ext/standard/php_mail.h"
  53. #include "ext/standard/exec.h"
  54. #include "ext/standard/php_smart_str.h"
  55. #include "ext/standard/url.h"
  56. #include "main/php_output.h"
  57. #include "ext/standard/info.h"
  58. #include "libmbfl/mbfl/mbfl_allocators.h"
  59. #include "php_variables.h"
  60. #include "php_globals.h"
  61. #include "rfc1867.h"
  62. #include "php_content_types.h"
  63. #include "SAPI.h"
  64. #include "php_unicode.h"
  65. #include "TSRM.h"
  66. #include "mb_gpc.h"
  67. #if HAVE_MBREGEX
  68. #include "php_mbregex.h"
  69. #endif
  70. #ifdef ZEND_MULTIBYTE
  71. #include "zend_multibyte.h"
  72. #endif /* ZEND_MULTIBYTE */
  73. #if HAVE_ONIG
  74. #include "php_onig_compat.h"
  75. #include <oniguruma.h>
  76. #undef UChar
  77. #elif HAVE_PCRE || HAVE_BUNDLED_PCRE
  78. #include "ext/pcre/php_pcre.h"
  79. #endif
  80. /* }}} */
  81. #if HAVE_MBSTRING
  82. /* {{{ prototypes */
  83. ZEND_DECLARE_MODULE_GLOBALS(mbstring)
  84. static PHP_GINIT_FUNCTION(mbstring);
  85. static PHP_GSHUTDOWN_FUNCTION(mbstring);
  86. /* }}} */
  87. /* {{{ php_mb_default_identify_list */
  88. typedef struct _php_mb_nls_ident_list {
  89. enum mbfl_no_language lang;
  90. const enum mbfl_no_encoding* list;
  91. int list_size;
  92. } php_mb_nls_ident_list;
  93. static const enum mbfl_no_encoding php_mb_default_identify_list_ja[] = {
  94. mbfl_no_encoding_ascii,
  95. mbfl_no_encoding_jis,
  96. mbfl_no_encoding_utf8,
  97. mbfl_no_encoding_euc_jp,
  98. mbfl_no_encoding_sjis
  99. };
  100. static const enum mbfl_no_encoding php_mb_default_identify_list_cn[] = {
  101. mbfl_no_encoding_ascii,
  102. mbfl_no_encoding_utf8,
  103. mbfl_no_encoding_euc_cn,
  104. mbfl_no_encoding_cp936
  105. };
  106. static const enum mbfl_no_encoding php_mb_default_identify_list_tw_hk[] = {
  107. mbfl_no_encoding_ascii,
  108. mbfl_no_encoding_utf8,
  109. mbfl_no_encoding_euc_tw,
  110. mbfl_no_encoding_big5
  111. };
  112. static const enum mbfl_no_encoding php_mb_default_identify_list_kr[] = {
  113. mbfl_no_encoding_ascii,
  114. mbfl_no_encoding_utf8,
  115. mbfl_no_encoding_euc_kr,
  116. mbfl_no_encoding_uhc
  117. };
  118. static const enum mbfl_no_encoding php_mb_default_identify_list_ru[] = {
  119. mbfl_no_encoding_ascii,
  120. mbfl_no_encoding_utf8,
  121. mbfl_no_encoding_koi8r,
  122. mbfl_no_encoding_cp1251,
  123. mbfl_no_encoding_cp866
  124. };
  125. static const enum mbfl_no_encoding php_mb_default_identify_list_hy[] = {
  126. mbfl_no_encoding_ascii,
  127. mbfl_no_encoding_utf8,
  128. mbfl_no_encoding_armscii8
  129. };
  130. static const enum mbfl_no_encoding php_mb_default_identify_list_tr[] = {
  131. mbfl_no_encoding_ascii,
  132. mbfl_no_encoding_utf8,
  133. mbfl_no_encoding_cp1254,
  134. mbfl_no_encoding_8859_9
  135. };
  136. static const enum mbfl_no_encoding php_mb_default_identify_list_ua[] = {
  137. mbfl_no_encoding_ascii,
  138. mbfl_no_encoding_utf8,
  139. mbfl_no_encoding_koi8u
  140. };
  141. static const enum mbfl_no_encoding php_mb_default_identify_list_neut[] = {
  142. mbfl_no_encoding_ascii,
  143. mbfl_no_encoding_utf8
  144. };
  145. static const php_mb_nls_ident_list php_mb_default_identify_list[] = {
  146. { mbfl_no_language_japanese, php_mb_default_identify_list_ja, sizeof(php_mb_default_identify_list_ja) / sizeof(php_mb_default_identify_list_ja[0]) },
  147. { mbfl_no_language_korean, php_mb_default_identify_list_kr, sizeof(php_mb_default_identify_list_kr) / sizeof(php_mb_default_identify_list_kr[0]) },
  148. { mbfl_no_language_traditional_chinese, php_mb_default_identify_list_tw_hk, sizeof(php_mb_default_identify_list_tw_hk) / sizeof(php_mb_default_identify_list_tw_hk[0]) },
  149. { mbfl_no_language_simplified_chinese, php_mb_default_identify_list_cn, sizeof(php_mb_default_identify_list_cn) / sizeof(php_mb_default_identify_list_cn[0]) },
  150. { mbfl_no_language_russian, php_mb_default_identify_list_ru, sizeof(php_mb_default_identify_list_ru) / sizeof(php_mb_default_identify_list_ru[0]) },
  151. { mbfl_no_language_armenian, php_mb_default_identify_list_hy, sizeof(php_mb_default_identify_list_hy) / sizeof(php_mb_default_identify_list_hy[0]) },
  152. { mbfl_no_language_turkish, php_mb_default_identify_list_tr, sizeof(php_mb_default_identify_list_tr) / sizeof(php_mb_default_identify_list_tr[0]) },
  153. { mbfl_no_language_ukrainian, php_mb_default_identify_list_ua, sizeof(php_mb_default_identify_list_ua) / sizeof(php_mb_default_identify_list_ua[0]) },
  154. { mbfl_no_language_neutral, php_mb_default_identify_list_neut, sizeof(php_mb_default_identify_list_neut) / sizeof(php_mb_default_identify_list_neut[0]) }
  155. };
  156. /* }}} */
  157. /* {{{ mb_overload_def mb_ovld[] */
  158. static const struct mb_overload_def mb_ovld[] = {
  159. {MB_OVERLOAD_MAIL, "mail", "mb_send_mail", "mb_orig_mail"},
  160. {MB_OVERLOAD_STRING, "strlen", "mb_strlen", "mb_orig_strlen"},
  161. {MB_OVERLOAD_STRING, "strpos", "mb_strpos", "mb_orig_strpos"},
  162. {MB_OVERLOAD_STRING, "strrpos", "mb_strrpos", "mb_orig_strrpos"},
  163. {MB_OVERLOAD_STRING, "stripos", "mb_stripos", "mb_orig_stripos"},
  164. {MB_OVERLOAD_STRING, "strripos", "mb_strripos", "mb_orig_stripos"},
  165. {MB_OVERLOAD_STRING, "strstr", "mb_strstr", "mb_orig_strstr"},
  166. {MB_OVERLOAD_STRING, "strrchr", "mb_strrchr", "mb_orig_strrchr"},
  167. {MB_OVERLOAD_STRING, "stristr", "mb_stristr", "mb_orig_stristr"},
  168. {MB_OVERLOAD_STRING, "substr", "mb_substr", "mb_orig_substr"},
  169. {MB_OVERLOAD_STRING, "strtolower", "mb_strtolower", "mb_orig_strtolower"},
  170. {MB_OVERLOAD_STRING, "strtoupper", "mb_strtoupper", "mb_orig_strtoupper"},
  171. {MB_OVERLOAD_STRING, "substr_count", "mb_substr_count", "mb_orig_substr_count"},
  172. #if HAVE_MBREGEX
  173. {MB_OVERLOAD_REGEX, "ereg", "mb_ereg", "mb_orig_ereg"},
  174. {MB_OVERLOAD_REGEX, "eregi", "mb_eregi", "mb_orig_eregi"},
  175. {MB_OVERLOAD_REGEX, "ereg_replace", "mb_ereg_replace", "mb_orig_ereg_replace"},
  176. {MB_OVERLOAD_REGEX, "eregi_replace", "mb_eregi_replace", "mb_orig_eregi_replace"},
  177. {MB_OVERLOAD_REGEX, "split", "mb_split", "mb_orig_split"},
  178. #endif
  179. {0, NULL, NULL, NULL}
  180. };
  181. /* }}} */
  182. /* {{{ arginfo */
  183. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_language, 0, 0, 0)
  184. ZEND_ARG_INFO(0, language)
  185. ZEND_END_ARG_INFO()
  186. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_internal_encoding, 0, 0, 0)
  187. ZEND_ARG_INFO(0, encoding)
  188. ZEND_END_ARG_INFO()
  189. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_http_input, 0, 0, 0)
  190. ZEND_ARG_INFO(0, type)
  191. ZEND_END_ARG_INFO()
  192. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_http_output, 0, 0, 0)
  193. ZEND_ARG_INFO(0, encoding)
  194. ZEND_END_ARG_INFO()
  195. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_detect_order, 0, 0, 0)
  196. ZEND_ARG_INFO(0, encoding)
  197. ZEND_END_ARG_INFO()
  198. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_substitute_character, 0, 0, 0)
  199. ZEND_ARG_INFO(0, substchar)
  200. ZEND_END_ARG_INFO()
  201. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_preferred_mime_name, 0, 0, 1)
  202. ZEND_ARG_INFO(0, encoding)
  203. ZEND_END_ARG_INFO()
  204. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_parse_str, 0, 0, 1)
  205. ZEND_ARG_INFO(0, encoded_string)
  206. ZEND_ARG_INFO(1, result)
  207. ZEND_END_ARG_INFO()
  208. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_output_handler, 0, 0, 2)
  209. ZEND_ARG_INFO(0, contents)
  210. ZEND_ARG_INFO(0, status)
  211. ZEND_END_ARG_INFO()
  212. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strlen, 0, 0, 1)
  213. ZEND_ARG_INFO(0, str)
  214. ZEND_ARG_INFO(0, encoding)
  215. ZEND_END_ARG_INFO()
  216. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strpos, 0, 0, 2)
  217. ZEND_ARG_INFO(0, haystack)
  218. ZEND_ARG_INFO(0, needle)
  219. ZEND_ARG_INFO(0, offset)
  220. ZEND_ARG_INFO(0, encoding)
  221. ZEND_END_ARG_INFO()
  222. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strrpos, 0, 0, 2)
  223. ZEND_ARG_INFO(0, haystack)
  224. ZEND_ARG_INFO(0, needle)
  225. ZEND_ARG_INFO(0, offset)
  226. ZEND_ARG_INFO(0, encoding)
  227. ZEND_END_ARG_INFO()
  228. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_stripos, 0, 0, 2)
  229. ZEND_ARG_INFO(0, haystack)
  230. ZEND_ARG_INFO(0, needle)
  231. ZEND_ARG_INFO(0, offset)
  232. ZEND_ARG_INFO(0, encoding)
  233. ZEND_END_ARG_INFO()
  234. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strripos, 0, 0, 2)
  235. ZEND_ARG_INFO(0, haystack)
  236. ZEND_ARG_INFO(0, needle)
  237. ZEND_ARG_INFO(0, offset)
  238. ZEND_ARG_INFO(0, encoding)
  239. ZEND_END_ARG_INFO()
  240. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strstr, 0, 0, 2)
  241. ZEND_ARG_INFO(0, haystack)
  242. ZEND_ARG_INFO(0, needle)
  243. ZEND_ARG_INFO(0, part)
  244. ZEND_ARG_INFO(0, encoding)
  245. ZEND_END_ARG_INFO()
  246. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strrchr, 0, 0, 2)
  247. ZEND_ARG_INFO(0, haystack)
  248. ZEND_ARG_INFO(0, needle)
  249. ZEND_ARG_INFO(0, part)
  250. ZEND_ARG_INFO(0, encoding)
  251. ZEND_END_ARG_INFO()
  252. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_stristr, 0, 0, 2)
  253. ZEND_ARG_INFO(0, haystack)
  254. ZEND_ARG_INFO(0, needle)
  255. ZEND_ARG_INFO(0, part)
  256. ZEND_ARG_INFO(0, encoding)
  257. ZEND_END_ARG_INFO()
  258. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strrichr, 0, 0, 2)
  259. ZEND_ARG_INFO(0, haystack)
  260. ZEND_ARG_INFO(0, needle)
  261. ZEND_ARG_INFO(0, part)
  262. ZEND_ARG_INFO(0, encoding)
  263. ZEND_END_ARG_INFO()
  264. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_substr_count, 0, 0, 2)
  265. ZEND_ARG_INFO(0, haystack)
  266. ZEND_ARG_INFO(0, needle)
  267. ZEND_ARG_INFO(0, encoding)
  268. ZEND_END_ARG_INFO()
  269. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_substr, 0, 0, 2)
  270. ZEND_ARG_INFO(0, str)
  271. ZEND_ARG_INFO(0, start)
  272. ZEND_ARG_INFO(0, length)
  273. ZEND_ARG_INFO(0, encoding)
  274. ZEND_END_ARG_INFO()
  275. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strcut, 0, 0, 2)
  276. ZEND_ARG_INFO(0, str)
  277. ZEND_ARG_INFO(0, start)
  278. ZEND_ARG_INFO(0, length)
  279. ZEND_ARG_INFO(0, encoding)
  280. ZEND_END_ARG_INFO()
  281. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strwidth, 0, 0, 1)
  282. ZEND_ARG_INFO(0, str)
  283. ZEND_ARG_INFO(0, encoding)
  284. ZEND_END_ARG_INFO()
  285. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strimwidth, 0, 0, 3)
  286. ZEND_ARG_INFO(0, str)
  287. ZEND_ARG_INFO(0, start)
  288. ZEND_ARG_INFO(0, width)
  289. ZEND_ARG_INFO(0, trimmarker)
  290. ZEND_ARG_INFO(0, encoding)
  291. ZEND_END_ARG_INFO()
  292. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_convert_encoding, 0, 0, 2)
  293. ZEND_ARG_INFO(0, str)
  294. ZEND_ARG_INFO(0, to)
  295. ZEND_ARG_INFO(0, from)
  296. ZEND_END_ARG_INFO()
  297. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_convert_case, 0, 0, 2)
  298. ZEND_ARG_INFO(0, sourcestring)
  299. ZEND_ARG_INFO(0, mode)
  300. ZEND_ARG_INFO(0, encoding)
  301. ZEND_END_ARG_INFO()
  302. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strtoupper, 0, 0, 1)
  303. ZEND_ARG_INFO(0, sourcestring)
  304. ZEND_ARG_INFO(0, encoding)
  305. ZEND_END_ARG_INFO()
  306. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_strtolower, 0, 0, 1)
  307. ZEND_ARG_INFO(0, sourcestring)
  308. ZEND_ARG_INFO(0, encoding)
  309. ZEND_END_ARG_INFO()
  310. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_detect_encoding, 0, 0, 1)
  311. ZEND_ARG_INFO(0, str)
  312. ZEND_ARG_INFO(0, encoding_list)
  313. ZEND_ARG_INFO(0, strict)
  314. ZEND_END_ARG_INFO()
  315. ZEND_BEGIN_ARG_INFO(arginfo_mb_list_encodings, 0)
  316. ZEND_END_ARG_INFO()
  317. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_encoding_aliases, 0, 0, 1)
  318. ZEND_ARG_INFO(0, encoding)
  319. ZEND_END_ARG_INFO()
  320. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_encode_mimeheader, 0, 0, 1)
  321. ZEND_ARG_INFO(0, str)
  322. ZEND_ARG_INFO(0, charset)
  323. ZEND_ARG_INFO(0, transfer)
  324. ZEND_ARG_INFO(0, linefeed)
  325. ZEND_ARG_INFO(0, indent)
  326. ZEND_END_ARG_INFO()
  327. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_decode_mimeheader, 0, 0, 1)
  328. ZEND_ARG_INFO(0, string)
  329. ZEND_END_ARG_INFO()
  330. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_convert_kana, 0, 0, 1)
  331. ZEND_ARG_INFO(0, str)
  332. ZEND_ARG_INFO(0, option)
  333. ZEND_ARG_INFO(0, encoding)
  334. ZEND_END_ARG_INFO()
  335. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_convert_variables, 1, 0, 3)
  336. ZEND_ARG_INFO(0, to)
  337. ZEND_ARG_INFO(0, from)
  338. ZEND_ARG_INFO(1, ...)
  339. ZEND_END_ARG_INFO()
  340. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_encode_numericentity, 0, 0, 2)
  341. ZEND_ARG_INFO(0, string)
  342. ZEND_ARG_INFO(0, convmap)
  343. ZEND_ARG_INFO(0, encoding)
  344. ZEND_END_ARG_INFO()
  345. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_decode_numericentity, 0, 0, 2)
  346. ZEND_ARG_INFO(0, string)
  347. ZEND_ARG_INFO(0, convmap)
  348. ZEND_ARG_INFO(0, encoding)
  349. ZEND_END_ARG_INFO()
  350. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_send_mail, 0, 0, 3)
  351. ZEND_ARG_INFO(0, to)
  352. ZEND_ARG_INFO(0, subject)
  353. ZEND_ARG_INFO(0, message)
  354. ZEND_ARG_INFO(0, additional_headers)
  355. ZEND_ARG_INFO(0, additional_parameters)
  356. ZEND_END_ARG_INFO()
  357. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_get_info, 0, 0, 0)
  358. ZEND_ARG_INFO(0, type)
  359. ZEND_END_ARG_INFO()
  360. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_check_encoding, 0, 0, 0)
  361. ZEND_ARG_INFO(0, var)
  362. ZEND_ARG_INFO(0, encoding)
  363. ZEND_END_ARG_INFO()
  364. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_regex_encoding, 0, 0, 0)
  365. ZEND_ARG_INFO(0, encoding)
  366. ZEND_END_ARG_INFO()
  367. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ereg, 0, 0, 2)
  368. ZEND_ARG_INFO(0, pattern)
  369. ZEND_ARG_INFO(0, string)
  370. ZEND_ARG_INFO(1, registers)
  371. ZEND_END_ARG_INFO()
  372. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_eregi, 0, 0, 2)
  373. ZEND_ARG_INFO(0, pattern)
  374. ZEND_ARG_INFO(0, string)
  375. ZEND_ARG_INFO(1, registers)
  376. ZEND_END_ARG_INFO()
  377. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ereg_replace, 0, 0, 3)
  378. ZEND_ARG_INFO(0, pattern)
  379. ZEND_ARG_INFO(0, replacement)
  380. ZEND_ARG_INFO(0, string)
  381. ZEND_ARG_INFO(0, option)
  382. ZEND_END_ARG_INFO()
  383. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_eregi_replace, 0, 0, 3)
  384. ZEND_ARG_INFO(0, pattern)
  385. ZEND_ARG_INFO(0, replacement)
  386. ZEND_ARG_INFO(0, string)
  387. ZEND_END_ARG_INFO()
  388. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_split, 0, 0, 2)
  389. ZEND_ARG_INFO(0, pattern)
  390. ZEND_ARG_INFO(0, string)
  391. ZEND_ARG_INFO(0, limit)
  392. ZEND_END_ARG_INFO()
  393. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ereg_match, 0, 0, 2)
  394. ZEND_ARG_INFO(0, pattern)
  395. ZEND_ARG_INFO(0, string)
  396. ZEND_ARG_INFO(0, option)
  397. ZEND_END_ARG_INFO()
  398. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ereg_search, 0, 0, 0)
  399. ZEND_ARG_INFO(0, pattern)
  400. ZEND_ARG_INFO(0, option)
  401. ZEND_END_ARG_INFO()
  402. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ereg_search_pos, 0, 0, 0)
  403. ZEND_ARG_INFO(0, pattern)
  404. ZEND_ARG_INFO(0, option)
  405. ZEND_END_ARG_INFO()
  406. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ereg_search_regs, 0, 0, 0)
  407. ZEND_ARG_INFO(0, pattern)
  408. ZEND_ARG_INFO(0, option)
  409. ZEND_END_ARG_INFO()
  410. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ereg_search_init, 0, 0, 1)
  411. ZEND_ARG_INFO(0, string)
  412. ZEND_ARG_INFO(0, pattern)
  413. ZEND_ARG_INFO(0, option)
  414. ZEND_END_ARG_INFO()
  415. ZEND_BEGIN_ARG_INFO(arginfo_mb_ereg_search_getregs, 0)
  416. ZEND_END_ARG_INFO()
  417. ZEND_BEGIN_ARG_INFO(arginfo_mb_ereg_search_getpos, 0)
  418. ZEND_END_ARG_INFO()
  419. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_ereg_search_setpos, 0, 0, 1)
  420. ZEND_ARG_INFO(0, position)
  421. ZEND_END_ARG_INFO()
  422. ZEND_BEGIN_ARG_INFO_EX(arginfo_mb_regex_set_options, 0, 0, 0)
  423. ZEND_ARG_INFO(0, options)
  424. ZEND_END_ARG_INFO()
  425. /* }}} */
  426. /* {{{ zend_function_entry mbstring_functions[] */
  427. const zend_function_entry mbstring_functions[] = {
  428. PHP_FE(mb_convert_case, arginfo_mb_convert_case)
  429. PHP_FE(mb_strtoupper, arginfo_mb_strtoupper)
  430. PHP_FE(mb_strtolower, arginfo_mb_strtolower)
  431. PHP_FE(mb_language, arginfo_mb_language)
  432. PHP_FE(mb_internal_encoding, arginfo_mb_internal_encoding)
  433. PHP_FE(mb_http_input, arginfo_mb_http_input)
  434. PHP_FE(mb_http_output, arginfo_mb_http_output)
  435. PHP_FE(mb_detect_order, arginfo_mb_detect_order)
  436. PHP_FE(mb_substitute_character, arginfo_mb_substitute_character)
  437. PHP_FE(mb_parse_str, arginfo_mb_parse_str)
  438. PHP_FE(mb_output_handler, arginfo_mb_output_handler)
  439. PHP_FE(mb_preferred_mime_name, arginfo_mb_preferred_mime_name)
  440. PHP_FE(mb_strlen, arginfo_mb_strlen)
  441. PHP_FE(mb_strpos, arginfo_mb_strpos)
  442. PHP_FE(mb_strrpos, arginfo_mb_strrpos)
  443. PHP_FE(mb_stripos, arginfo_mb_stripos)
  444. PHP_FE(mb_strripos, arginfo_mb_strripos)
  445. PHP_FE(mb_strstr, arginfo_mb_strstr)
  446. PHP_FE(mb_strrchr, arginfo_mb_strrchr)
  447. PHP_FE(mb_stristr, arginfo_mb_stristr)
  448. PHP_FE(mb_strrichr, arginfo_mb_strrichr)
  449. PHP_FE(mb_substr_count, arginfo_mb_substr_count)
  450. PHP_FE(mb_substr, arginfo_mb_substr)
  451. PHP_FE(mb_strcut, arginfo_mb_strcut)
  452. PHP_FE(mb_strwidth, arginfo_mb_strwidth)
  453. PHP_FE(mb_strimwidth, arginfo_mb_strimwidth)
  454. PHP_FE(mb_convert_encoding, arginfo_mb_convert_encoding)
  455. PHP_FE(mb_detect_encoding, arginfo_mb_detect_encoding)
  456. PHP_FE(mb_list_encodings, arginfo_mb_list_encodings)
  457. PHP_FE(mb_encoding_aliases, arginfo_mb_encoding_aliases)
  458. PHP_FE(mb_convert_kana, arginfo_mb_convert_kana)
  459. PHP_FE(mb_encode_mimeheader, arginfo_mb_encode_mimeheader)
  460. PHP_FE(mb_decode_mimeheader, arginfo_mb_decode_mimeheader)
  461. PHP_FE(mb_convert_variables, arginfo_mb_convert_variables)
  462. PHP_FE(mb_encode_numericentity, arginfo_mb_encode_numericentity)
  463. PHP_FE(mb_decode_numericentity, arginfo_mb_decode_numericentity)
  464. PHP_FE(mb_send_mail, arginfo_mb_send_mail)
  465. PHP_FE(mb_get_info, arginfo_mb_get_info)
  466. PHP_FE(mb_check_encoding, arginfo_mb_check_encoding)
  467. #if HAVE_MBREGEX
  468. PHP_MBREGEX_FUNCTION_ENTRIES
  469. #endif
  470. { NULL, NULL, NULL }
  471. };
  472. /* }}} */
  473. /* {{{ zend_module_entry mbstring_module_entry */
  474. zend_module_entry mbstring_module_entry = {
  475. STANDARD_MODULE_HEADER,
  476. "mbstring",
  477. mbstring_functions,
  478. PHP_MINIT(mbstring),
  479. PHP_MSHUTDOWN(mbstring),
  480. PHP_RINIT(mbstring),
  481. PHP_RSHUTDOWN(mbstring),
  482. PHP_MINFO(mbstring),
  483. NO_VERSION_YET,
  484. PHP_MODULE_GLOBALS(mbstring),
  485. PHP_GINIT(mbstring),
  486. PHP_GSHUTDOWN(mbstring),
  487. NULL,
  488. STANDARD_MODULE_PROPERTIES_EX
  489. };
  490. /* }}} */
  491. /* {{{ static sapi_post_entry php_post_entries[] */
  492. static sapi_post_entry php_post_entries[] = {
  493. { DEFAULT_POST_CONTENT_TYPE, sizeof(DEFAULT_POST_CONTENT_TYPE)-1, sapi_read_standard_form_data, php_std_post_handler },
  494. { MULTIPART_CONTENT_TYPE, sizeof(MULTIPART_CONTENT_TYPE)-1, NULL, rfc1867_post_handler },
  495. { NULL, 0, NULL, NULL }
  496. };
  497. /* }}} */
  498. #ifdef COMPILE_DL_MBSTRING
  499. ZEND_GET_MODULE(mbstring)
  500. #endif
  501. /* {{{ allocators */
  502. static void *_php_mb_allocators_malloc(unsigned int sz)
  503. {
  504. return emalloc(sz);
  505. }
  506. static void *_php_mb_allocators_realloc(void *ptr, unsigned int sz)
  507. {
  508. return erealloc(ptr, sz);
  509. }
  510. static void *_php_mb_allocators_calloc(unsigned int nelems, unsigned int szelem)
  511. {
  512. return ecalloc(nelems, szelem);
  513. }
  514. static void _php_mb_allocators_free(void *ptr)
  515. {
  516. efree(ptr);
  517. }
  518. static void *_php_mb_allocators_pmalloc(unsigned int sz)
  519. {
  520. return pemalloc(sz, 1);
  521. }
  522. static void *_php_mb_allocators_prealloc(void *ptr, unsigned int sz)
  523. {
  524. return perealloc(ptr, sz, 1);
  525. }
  526. static void _php_mb_allocators_pfree(void *ptr)
  527. {
  528. pefree(ptr, 1);
  529. }
  530. static mbfl_allocators _php_mb_allocators = {
  531. _php_mb_allocators_malloc,
  532. _php_mb_allocators_realloc,
  533. _php_mb_allocators_calloc,
  534. _php_mb_allocators_free,
  535. _php_mb_allocators_pmalloc,
  536. _php_mb_allocators_prealloc,
  537. _php_mb_allocators_pfree
  538. };
  539. /* }}} */
  540. /* {{{ static sapi_post_entry mbstr_post_entries[] */
  541. static sapi_post_entry mbstr_post_entries[] = {
  542. { DEFAULT_POST_CONTENT_TYPE, sizeof(DEFAULT_POST_CONTENT_TYPE)-1, sapi_read_standard_form_data, php_mb_post_handler },
  543. { MULTIPART_CONTENT_TYPE, sizeof(MULTIPART_CONTENT_TYPE)-1, NULL, rfc1867_post_handler },
  544. { NULL, 0, NULL, NULL }
  545. };
  546. /* }}} */
  547. /* {{{ static int php_mb_parse_encoding_list()
  548. * Return 0 if input contains any illegal encoding, otherwise 1.
  549. * Even if any illegal encoding is detected the result may contain a list
  550. * of parsed encodings.
  551. */
  552. static int
  553. php_mb_parse_encoding_list(const char *value, int value_length, enum mbfl_no_encoding **return_list, int *return_size, int persistent TSRMLS_DC)
  554. {
  555. int n, l, size, bauto, ret = 1;
  556. char *p, *p1, *p2, *endp, *tmpstr;
  557. enum mbfl_no_encoding no_encoding;
  558. enum mbfl_no_encoding *src, *entry, *list;
  559. list = NULL;
  560. if (value == NULL || value_length <= 0) {
  561. if (return_list) {
  562. *return_list = NULL;
  563. }
  564. if (return_size) {
  565. *return_size = 0;
  566. }
  567. return 0;
  568. } else {
  569. enum mbfl_no_encoding *identify_list;
  570. int identify_list_size;
  571. identify_list = MBSTRG(default_detect_order_list);
  572. identify_list_size = MBSTRG(default_detect_order_list_size);
  573. /* copy the value string for work */
  574. if (value[0]=='"' && value[value_length-1]=='"' && value_length>2) {
  575. tmpstr = (char *)estrndup(value+1, value_length-2);
  576. value_length -= 2;
  577. }
  578. else
  579. tmpstr = (char *)estrndup(value, value_length);
  580. if (tmpstr == NULL) {
  581. return 0;
  582. }
  583. /* count the number of listed encoding names */
  584. endp = tmpstr + value_length;
  585. n = 1;
  586. p1 = tmpstr;
  587. while ((p2 = php_memnstr(p1, ",", 1, endp)) != NULL) {
  588. p1 = p2 + 1;
  589. n++;
  590. }
  591. size = n + identify_list_size;
  592. /* make list */
  593. list = (enum mbfl_no_encoding *)pecalloc(size, sizeof(int), persistent);
  594. if (list != NULL) {
  595. entry = list;
  596. n = 0;
  597. bauto = 0;
  598. p1 = tmpstr;
  599. do {
  600. p2 = p = php_memnstr(p1, ",", 1, endp);
  601. if (p == NULL) {
  602. p = endp;
  603. }
  604. *p = '\0';
  605. /* trim spaces */
  606. while (p1 < p && (*p1 == ' ' || *p1 == '\t')) {
  607. p1++;
  608. }
  609. p--;
  610. while (p > p1 && (*p == ' ' || *p == '\t')) {
  611. *p = '\0';
  612. p--;
  613. }
  614. /* convert to the encoding number and check encoding */
  615. if (strcasecmp(p1, "auto") == 0) {
  616. if (!bauto) {
  617. bauto = 1;
  618. l = identify_list_size;
  619. src = identify_list;
  620. while (l > 0) {
  621. *entry++ = *src++;
  622. l--;
  623. n++;
  624. }
  625. }
  626. } else {
  627. no_encoding = mbfl_name2no_encoding(p1);
  628. if (no_encoding != mbfl_no_encoding_invalid) {
  629. *entry++ = no_encoding;
  630. n++;
  631. } else {
  632. ret = 0;
  633. }
  634. }
  635. p1 = p2 + 1;
  636. } while (n < size && p2 != NULL);
  637. if (n > 0) {
  638. if (return_list) {
  639. *return_list = list;
  640. } else {
  641. pefree(list, persistent);
  642. }
  643. } else {
  644. pefree(list, persistent);
  645. if (return_list) {
  646. *return_list = NULL;
  647. }
  648. ret = 0;
  649. }
  650. if (return_size) {
  651. *return_size = n;
  652. }
  653. } else {
  654. if (return_list) {
  655. *return_list = NULL;
  656. }
  657. if (return_size) {
  658. *return_size = 0;
  659. }
  660. ret = 0;
  661. }
  662. efree(tmpstr);
  663. }
  664. return ret;
  665. }
  666. /* }}} */
  667. /* {{{ MBSTRING_API php_mb_check_encoding_list */
  668. MBSTRING_API int php_mb_check_encoding_list(const char *encoding_list TSRMLS_DC) {
  669. return php_mb_parse_encoding_list(encoding_list, strlen(encoding_list), NULL, NULL, 0 TSRMLS_CC);
  670. }
  671. /* }}} */
  672. /* {{{ static int php_mb_parse_encoding_array()
  673. * Return 0 if input contains any illegal encoding, otherwise 1.
  674. * Even if any illegal encoding is detected the result may contain a list
  675. * of parsed encodings.
  676. */
  677. static int
  678. php_mb_parse_encoding_array(zval *array, enum mbfl_no_encoding **return_list, int *return_size, int persistent TSRMLS_DC)
  679. {
  680. zval **hash_entry;
  681. HashTable *target_hash;
  682. int i, n, l, size, bauto,ret = 1;
  683. enum mbfl_no_encoding no_encoding;
  684. enum mbfl_no_encoding *src, *list, *entry;
  685. list = NULL;
  686. if (Z_TYPE_P(array) == IS_ARRAY) {
  687. enum mbfl_no_encoding *identify_list;
  688. int identify_list_size;
  689. identify_list = MBSTRG(default_detect_order_list);
  690. identify_list_size = MBSTRG(default_detect_order_list_size);
  691. target_hash = Z_ARRVAL_P(array);
  692. zend_hash_internal_pointer_reset(target_hash);
  693. i = zend_hash_num_elements(target_hash);
  694. size = i + identify_list_size;
  695. list = (enum mbfl_no_encoding *)pecalloc(size, sizeof(int), persistent);
  696. if (list != NULL) {
  697. entry = list;
  698. bauto = 0;
  699. n = 0;
  700. while (i > 0) {
  701. if (zend_hash_get_current_data(target_hash, (void **) &hash_entry) == FAILURE) {
  702. break;
  703. }
  704. convert_to_string_ex(hash_entry);
  705. if (strcasecmp(Z_STRVAL_PP(hash_entry), "auto") == 0) {
  706. if (!bauto) {
  707. bauto = 1;
  708. l = identify_list_size;
  709. src = identify_list;
  710. while (l > 0) {
  711. *entry++ = *src++;
  712. l--;
  713. n++;
  714. }
  715. }
  716. } else {
  717. no_encoding = mbfl_name2no_encoding(Z_STRVAL_PP(hash_entry));
  718. if (no_encoding != mbfl_no_encoding_invalid) {
  719. *entry++ = no_encoding;
  720. n++;
  721. } else {
  722. ret = 0;
  723. }
  724. }
  725. zend_hash_move_forward(target_hash);
  726. i--;
  727. }
  728. if (n > 0) {
  729. if (return_list) {
  730. *return_list = list;
  731. } else {
  732. pefree(list, persistent);
  733. }
  734. } else {
  735. pefree(list, persistent);
  736. if (return_list) {
  737. *return_list = NULL;
  738. }
  739. ret = 0;
  740. }
  741. if (return_size) {
  742. *return_size = n;
  743. }
  744. } else {
  745. if (return_list) {
  746. *return_list = NULL;
  747. }
  748. if (return_size) {
  749. *return_size = 0;
  750. }
  751. ret = 0;
  752. }
  753. }
  754. return ret;
  755. }
  756. /* }}} */
  757. static void *_php_mb_compile_regex(const char *pattern TSRMLS_DC);
  758. static int _php_mb_match_regex(void *opaque, const char *str, size_t str_len);
  759. static void _php_mb_free_regex(void *opaque);
  760. #if HAVE_ONIG
  761. /* {{{ _php_mb_compile_regex */
  762. void *_php_mb_compile_regex(const char *pattern TSRMLS_DC)
  763. {
  764. php_mb_regex_t *retval;
  765. OnigErrorInfo err_info;
  766. int err_code;
  767. if ((err_code = onig_new(&retval,
  768. (const OnigUChar *)pattern,
  769. (const OnigUChar *)pattern + strlen(pattern),
  770. ONIG_OPTION_IGNORECASE | ONIG_OPTION_DONT_CAPTURE_GROUP,
  771. ONIG_ENCODING_ASCII, &OnigSyntaxPerl, &err_info))) {
  772. OnigUChar err_str[ONIG_MAX_ERROR_MESSAGE_LEN];
  773. onig_error_code_to_str(err_str, err_code, err_info);
  774. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s: %s", pattern, err_str);
  775. retval = NULL;
  776. }
  777. return retval;
  778. }
  779. /* }}} */
  780. /* {{{ _php_mb_match_regex */
  781. int _php_mb_match_regex(void *opaque, const char *str, size_t str_len)
  782. {
  783. return onig_search((php_mb_regex_t *)opaque, (const OnigUChar *)str,
  784. (const OnigUChar*)str + str_len, (const OnigUChar *)str,
  785. (const OnigUChar*)str + str_len, NULL, ONIG_OPTION_NONE) >= 0;
  786. }
  787. /* }}} */
  788. /* {{{ _php_mb_free_regex */
  789. void _php_mb_free_regex(void *opaque)
  790. {
  791. onig_free((php_mb_regex_t *)opaque);
  792. }
  793. /* }}} */
  794. #elif HAVE_PCRE || HAVE_BUNDLED_PCRE
  795. /* {{{ _php_mb_compile_regex */
  796. void *_php_mb_compile_regex(const char *pattern TSRMLS_DC)
  797. {
  798. pcre *retval;
  799. const char *err_str;
  800. int err_offset;
  801. if (!(retval = pcre_compile(pattern,
  802. PCRE_CASELESS, &err_str, &err_offset, NULL))) {
  803. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s (offset=%d): %s", pattern, err_offset, err_str);
  804. }
  805. return retval;
  806. }
  807. /* }}} */
  808. /* {{{ _php_mb_match_regex */
  809. int _php_mb_match_regex(void *opaque, const char *str, size_t str_len)
  810. {
  811. return pcre_exec((pcre *)opaque, NULL, str, (int)str_len, 0,
  812. 0, NULL, 0) >= 0;
  813. }
  814. /* }}} */
  815. /* {{{ _php_mb_free_regex */
  816. void _php_mb_free_regex(void *opaque)
  817. {
  818. pcre_free(opaque);
  819. }
  820. /* }}} */
  821. #endif
  822. /* {{{ php_mb_nls_get_default_detect_order_list */
  823. static int php_mb_nls_get_default_detect_order_list(enum mbfl_no_language lang, enum mbfl_no_encoding **plist, int* plist_size)
  824. {
  825. size_t i;
  826. *plist = (enum mbfl_no_encoding *) php_mb_default_identify_list_neut;
  827. *plist_size = sizeof(php_mb_default_identify_list_neut) / sizeof(php_mb_default_identify_list_neut[0]);
  828. for (i = 0; i < sizeof(php_mb_default_identify_list) / sizeof(php_mb_default_identify_list[0]); i++) {
  829. if (php_mb_default_identify_list[i].lang == lang) {
  830. *plist = (enum mbfl_no_encoding *)php_mb_default_identify_list[i].list;
  831. *plist_size = php_mb_default_identify_list[i].list_size;
  832. return 1;
  833. }
  834. }
  835. return 0;
  836. }
  837. /* }}} */
  838. /* {{{ php.ini directive handler */
  839. /* {{{ static PHP_INI_MH(OnUpdate_mbstring_language) */
  840. static PHP_INI_MH(OnUpdate_mbstring_language)
  841. {
  842. enum mbfl_no_language no_language;
  843. no_language = mbfl_name2no_language(new_value);
  844. if (no_language == mbfl_no_language_invalid) {
  845. MBSTRG(language) = mbfl_no_language_neutral;
  846. return FAILURE;
  847. }
  848. MBSTRG(language) = no_language;
  849. php_mb_nls_get_default_detect_order_list(no_language, &MBSTRG(default_detect_order_list), &MBSTRG(default_detect_order_list_size));
  850. return SUCCESS;
  851. }
  852. /* }}} */
  853. /* {{{ static PHP_INI_MH(OnUpdate_mbstring_detect_order) */
  854. static PHP_INI_MH(OnUpdate_mbstring_detect_order)
  855. {
  856. enum mbfl_no_encoding *list;
  857. int size;
  858. if (php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1 TSRMLS_CC)) {
  859. if (MBSTRG(detect_order_list)) {
  860. free(MBSTRG(detect_order_list));
  861. }
  862. MBSTRG(detect_order_list) = list;
  863. MBSTRG(detect_order_list_size) = size;
  864. } else {
  865. if (MBSTRG(detect_order_list)) {
  866. free(MBSTRG(detect_order_list));
  867. MBSTRG(detect_order_list) = NULL;
  868. }
  869. return FAILURE;
  870. }
  871. return SUCCESS;
  872. }
  873. /* }}} */
  874. /* {{{ static PHP_INI_MH(OnUpdate_mbstring_http_input) */
  875. static PHP_INI_MH(OnUpdate_mbstring_http_input)
  876. {
  877. enum mbfl_no_encoding *list;
  878. int size;
  879. if (php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1 TSRMLS_CC)) {
  880. if (MBSTRG(http_input_list)) {
  881. free(MBSTRG(http_input_list));
  882. }
  883. MBSTRG(http_input_list) = list;
  884. MBSTRG(http_input_list_size) = size;
  885. } else {
  886. if (MBSTRG(http_input_list)) {
  887. free(MBSTRG(http_input_list));
  888. MBSTRG(http_input_list) = NULL;
  889. }
  890. MBSTRG(http_input_list_size) = 0;
  891. return FAILURE;
  892. }
  893. return SUCCESS;
  894. }
  895. /* }}} */
  896. /* {{{ static PHP_INI_MH(OnUpdate_mbstring_http_output) */
  897. static PHP_INI_MH(OnUpdate_mbstring_http_output)
  898. {
  899. enum mbfl_no_encoding no_encoding;
  900. no_encoding = mbfl_name2no_encoding(new_value);
  901. if (no_encoding != mbfl_no_encoding_invalid) {
  902. MBSTRG(http_output_encoding) = no_encoding;
  903. MBSTRG(current_http_output_encoding) = no_encoding;
  904. } else {
  905. MBSTRG(http_output_encoding) = mbfl_no_encoding_pass;
  906. MBSTRG(current_http_output_encoding) = mbfl_no_encoding_pass;
  907. if (new_value != NULL && new_value_length > 0) {
  908. return FAILURE;
  909. }
  910. }
  911. return SUCCESS;
  912. }
  913. /* }}} */
  914. /* {{{ static _php_mb_ini_mbstring_internal_encoding_set */
  915. int _php_mb_ini_mbstring_internal_encoding_set(const char *new_value, uint new_value_length TSRMLS_DC)
  916. {
  917. enum mbfl_no_encoding no_encoding;
  918. const char *enc_name = NULL;
  919. uint enc_name_len = 0;
  920. no_encoding = new_value ? mbfl_name2no_encoding(new_value):
  921. mbfl_no_encoding_invalid;
  922. if (no_encoding != mbfl_no_encoding_invalid) {
  923. enc_name = new_value;
  924. enc_name_len = new_value_length;
  925. } else {
  926. switch (MBSTRG(language)) {
  927. case mbfl_no_language_uni:
  928. enc_name = "UTF-8";
  929. enc_name_len = sizeof("UTF-8") - 1;
  930. break;
  931. case mbfl_no_language_japanese:
  932. enc_name = "EUC-JP";
  933. enc_name_len = sizeof("EUC-JP") - 1;
  934. break;
  935. case mbfl_no_language_korean:
  936. enc_name = "EUC-KR";
  937. enc_name_len = sizeof("EUC-KR") - 1;
  938. break;
  939. case mbfl_no_language_simplified_chinese:
  940. enc_name = "EUC-CN";
  941. enc_name_len = sizeof("EUC-CN") - 1;
  942. break;
  943. case mbfl_no_language_traditional_chinese:
  944. enc_name = "EUC-TW";
  945. enc_name_len = sizeof("EUC-TW") - 1;
  946. break;
  947. case mbfl_no_language_russian:
  948. enc_name = "KOI8-R";
  949. enc_name_len = sizeof("KOI8-R") - 1;
  950. break;
  951. case mbfl_no_language_german:
  952. enc_name = "ISO-8859-15";
  953. enc_name_len = sizeof("ISO-8859-15") - 1;
  954. break;
  955. case mbfl_no_language_armenian:
  956. enc_name = "ArmSCII-8";
  957. enc_name_len = sizeof("ArmSCII-8") - 1;
  958. break;
  959. case mbfl_no_language_turkish:
  960. enc_name = "ISO-8859-9";
  961. enc_name_len = sizeof("ISO-8859-9") - 1;
  962. break;
  963. default:
  964. enc_name = "ISO-8859-1";
  965. enc_name_len = sizeof("ISO-8859-1") - 1;
  966. break;
  967. }
  968. no_encoding = mbfl_name2no_encoding(enc_name);
  969. }
  970. MBSTRG(internal_encoding) = no_encoding;
  971. MBSTRG(current_internal_encoding) = no_encoding;
  972. #if HAVE_MBREGEX
  973. {
  974. const char *enc_name = new_value;
  975. if (FAILURE == php_mb_regex_set_default_mbctype(enc_name TSRMLS_CC)) {
  976. /* falls back to EUC-JP if an unknown encoding name is given */
  977. enc_name = "EUC-JP";
  978. php_mb_regex_set_default_mbctype(enc_name TSRMLS_CC);
  979. }
  980. php_mb_regex_set_mbctype(new_value TSRMLS_CC);
  981. }
  982. #endif
  983. return SUCCESS;
  984. }
  985. /* }}} */
  986. /* {{{ static PHP_INI_MH(OnUpdate_mbstring_internal_encoding) */
  987. static PHP_INI_MH(OnUpdate_mbstring_internal_encoding)
  988. {
  989. if (stage == PHP_INI_STAGE_STARTUP || stage == PHP_INI_STAGE_SHUTDOWN
  990. || stage == PHP_INI_STAGE_RUNTIME) {
  991. return _php_mb_ini_mbstring_internal_encoding_set(new_value, new_value_length TSRMLS_CC);
  992. } else {
  993. /* the corresponding mbstring globals needs to be set according to the
  994. * ini value in the later stage because it never falls back to the
  995. * default value if 1. no value for mbstring.internal_encoding is given,
  996. * 2. mbstring.language directive is processed in per-dir or runtime
  997. * context and 3. call to the handler for mbstring.language is done
  998. * after mbstring.internal_encoding is handled. */
  999. return SUCCESS;
  1000. }
  1001. }
  1002. /* }}} */
  1003. #ifdef ZEND_MULTIBYTE
  1004. /* {{{ static PHP_INI_MH(OnUpdate_mbstring_script_encoding) */
  1005. static PHP_INI_MH(OnUpdate_mbstring_script_encoding)
  1006. {
  1007. int *list, size;
  1008. if (php_mb_parse_encoding_list(new_value, new_value_length, &list, &size, 1 TSRMLS_CC)) {
  1009. if (MBSTRG(script_encoding_list) != NULL) {
  1010. free(MBSTRG(script_encoding_list));
  1011. }
  1012. MBSTRG(script_encoding_list) = list;
  1013. MBSTRG(script_encoding_list_size) = size;
  1014. } else {
  1015. if (MBSTRG(script_encoding_list) != NULL) {
  1016. free(MBSTRG(script_encoding_list));
  1017. }
  1018. MBSTRG(script_encoding_list) = NULL;
  1019. MBSTRG(script_encoding_list_size) = 0;
  1020. return FAILURE;
  1021. }
  1022. return SUCCESS;
  1023. }
  1024. /* }}} */
  1025. #endif /* ZEND_MULTIBYTE */
  1026. /* {{{ static PHP_INI_MH(OnUpdate_mbstring_substitute_character) */
  1027. static PHP_INI_MH(OnUpdate_mbstring_substitute_character)
  1028. {
  1029. int c;
  1030. char *endptr = NULL;
  1031. if (new_value != NULL) {
  1032. if (strcasecmp("none", new_value) == 0) {
  1033. MBSTRG(filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE;
  1034. MBSTRG(current_filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_NONE;
  1035. } else if (strcasecmp("long", new_value) == 0) {
  1036. MBSTRG(filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_LONG;
  1037. MBSTRG(current_filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_LONG;
  1038. } else if (strcasecmp("entity", new_value) == 0) {
  1039. MBSTRG(filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_ENTITY;
  1040. MBSTRG(current_filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_ENTITY;
  1041. } else {
  1042. MBSTRG(filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR;
  1043. MBSTRG(current_filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR;
  1044. if (new_value_length >0) {
  1045. c = strtol(new_value, &endptr, 0);
  1046. if (*endptr == '\0') {
  1047. MBSTRG(filter_illegal_substchar) = c;
  1048. MBSTRG(current_filter_illegal_substchar) = c;
  1049. }
  1050. }
  1051. }
  1052. } else {
  1053. MBSTRG(filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR;
  1054. MBSTRG(current_filter_illegal_mode) = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR;
  1055. MBSTRG(filter_illegal_substchar) = 0x3f; /* '?' */
  1056. MBSTRG(current_filter_illegal_substchar) = 0x3f; /* '?' */
  1057. }
  1058. return SUCCESS;
  1059. }
  1060. /* }}} */
  1061. /* {{{ static PHP_INI_MH(OnUpdate_mbstring_encoding_translation) */
  1062. static PHP_INI_MH(OnUpdate_mbstring_encoding_translation)
  1063. {
  1064. if (new_value == NULL) {
  1065. return FAILURE;
  1066. }
  1067. OnUpdateBool(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC);
  1068. if (MBSTRG(encoding_translation)) {
  1069. sapi_unregister_post_entry(php_post_entries TSRMLS_CC);
  1070. sapi_register_post_entries(mbstr_post_entries TSRMLS_CC);
  1071. } else {
  1072. sapi_unregister_post_entry(mbstr_post_entries TSRMLS_CC);
  1073. sapi_register_post_entries(php_post_entries TSRMLS_CC);
  1074. }
  1075. return SUCCESS;
  1076. }
  1077. /* }}} */
  1078. /* {{{ static PHP_INI_MH(OnUpdate_mbstring_http_output_conv_mimetypes */
  1079. static PHP_INI_MH(OnUpdate_mbstring_http_output_conv_mimetypes)
  1080. {
  1081. zval tmp;
  1082. void *re = NULL;
  1083. if (!new_value) {
  1084. new_value = entry->orig_value;
  1085. new_value_length = entry->orig_value_length;
  1086. }
  1087. php_trim(new_value, new_value_length, NULL, 0, &tmp, 3 TSRMLS_CC);
  1088. if (Z_STRLEN(tmp) > 0) {
  1089. if (!(re = _php_mb_compile_regex(Z_STRVAL(tmp) TSRMLS_CC))) {
  1090. zval_dtor(&tmp);
  1091. return FAILURE;
  1092. }
  1093. }
  1094. if (MBSTRG(http_output_conv_mimetypes)) {
  1095. _php_mb_free_regex(MBSTRG(http_output_conv_mimetypes));
  1096. }
  1097. MBSTRG(http_output_conv_mimetypes) = re;
  1098. zval_dtor(&tmp);
  1099. return SUCCESS;
  1100. }
  1101. /* }}} */
  1102. /* }}} */
  1103. /* {{{ php.ini directive registration */
  1104. PHP_INI_BEGIN()
  1105. PHP_INI_ENTRY("mbstring.language", "neutral", PHP_INI_ALL, OnUpdate_mbstring_language)
  1106. PHP_INI_ENTRY("mbstring.detect_order", NULL, PHP_INI_ALL, OnUpdate_mbstring_detect_order)
  1107. PHP_INI_ENTRY("mbstring.http_input", "pass", PHP_INI_ALL, OnUpdate_mbstring_http_input)
  1108. PHP_INI_ENTRY("mbstring.http_output", "pass", PHP_INI_ALL, OnUpdate_mbstring_http_output)
  1109. PHP_INI_ENTRY("mbstring.internal_encoding", NULL, PHP_INI_ALL, OnUpdate_mbstring_internal_encoding)
  1110. #ifdef ZEND_MULTIBYTE
  1111. PHP_INI_ENTRY("mbstring.script_encoding", NULL, PHP_INI_ALL, OnUpdate_mbstring_script_encoding)
  1112. #endif /* ZEND_MULTIBYTE */
  1113. PHP_INI_ENTRY("mbstring.substitute_character", NULL, PHP_INI_ALL, OnUpdate_mbstring_substitute_character)
  1114. STD_PHP_INI_ENTRY("mbstring.func_overload", "0",
  1115. PHP_INI_SYSTEM, OnUpdateLong, func_overload, zend_mbstring_globals, mbstring_globals)
  1116. STD_PHP_INI_BOOLEAN("mbstring.encoding_translation", "0",
  1117. PHP_INI_SYSTEM | PHP_INI_PERDIR,
  1118. OnUpdate_mbstring_encoding_translation,
  1119. encoding_translation, zend_mbstring_globals, mbstring_globals)
  1120. PHP_INI_ENTRY("mbstring.http_output_conv_mimetypes",
  1121. "^(text/|application/xhtml\\+xml)",
  1122. PHP_INI_ALL,
  1123. OnUpdate_mbstring_http_output_conv_mimetypes)
  1124. STD_PHP_INI_BOOLEAN("mbstring.strict_detection", "0",
  1125. PHP_INI_ALL,
  1126. OnUpdateLong,
  1127. strict_detection, zend_mbstring_globals, mbstring_globals)
  1128. PHP_INI_END()
  1129. /* }}} */
  1130. /* {{{ module global initialize handler */
  1131. static PHP_GINIT_FUNCTION(mbstring)
  1132. {
  1133. mbstring_globals->language = mbfl_no_language_uni;
  1134. mbstring_globals->internal_encoding = mbfl_no_encoding_invalid;
  1135. mbstring_globals->current_internal_encoding = mbstring_globals->internal_encoding;
  1136. #ifdef ZEND_MULTIBYTE
  1137. mbstring_globals->script_encoding_list = NULL;
  1138. mbstring_globals->script_encoding_list_size = 0;
  1139. #endif /* ZEND_MULTIBYTE */
  1140. mbstring_globals->http_output_encoding = mbfl_no_encoding_pass;
  1141. mbstring_globals->current_http_output_encoding = mbfl_no_encoding_pass;
  1142. mbstring_globals->http_input_identify = mbfl_no_encoding_invalid;
  1143. mbstring_globals->http_input_identify_get = mbfl_no_encoding_invalid;
  1144. mbstring_globals->http_input_identify_post = mbfl_no_encoding_invalid;
  1145. mbstring_globals->http_input_identify_cookie = mbfl_no_encoding_invalid;
  1146. mbstring_globals->http_input_identify_string = mbfl_no_encoding_invalid;
  1147. mbstring_globals->http_input_list = NULL;
  1148. mbstring_globals->http_input_list_size = 0;
  1149. mbstring_globals->detect_order_list = NULL;
  1150. mbstring_globals->detect_order_list_size = 0;
  1151. mbstring_globals->current_detect_order_list = NULL;
  1152. mbstring_globals->current_detect_order_list_size = 0;
  1153. mbstring_globals->default_detect_order_list = (enum mbfl_no_encoding *) php_mb_default_identify_list_neut;
  1154. mbstring_globals->default_detect_order_list_size = sizeof(php_mb_default_identify_list_neut) / sizeof(php_mb_default_identify_list_neut[0]);
  1155. mbstring_globals->filter_illegal_mode = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR;
  1156. mbstring_globals->filter_illegal_substchar = 0x3f; /* '?' */
  1157. mbstring_globals->current_filter_illegal_mode = MBFL_OUTPUTFILTER_ILLEGAL_MODE_CHAR;
  1158. mbstring_globals->current_filter_illegal_substchar = 0x3f; /* '?' */
  1159. mbstring_globals->illegalchars = 0;
  1160. mbstring_globals->func_overload = 0;
  1161. mbstring_globals->encoding_translation = 0;
  1162. mbstring_globals->strict_detection = 0;
  1163. mbstring_globals->outconv = NULL;
  1164. mbstring_globals->http_output_conv_mimetypes = NULL;
  1165. #if HAVE_MBREGEX
  1166. mbstring_globals->mb_regex_globals = php_mb_regex_globals_alloc(TSRMLS_C);
  1167. #endif
  1168. }
  1169. /* }}} */
  1170. /* {{{ PHP_GSHUTDOWN_FUNCTION */
  1171. static PHP_GSHUTDOWN_FUNCTION(mbstring)
  1172. {
  1173. if (mbstring_globals->http_input_list) {
  1174. free(mbstring_globals->http_input_list);
  1175. }
  1176. #ifdef ZEND_MULTIBYTE
  1177. if (mbstring_globals->script_encoding_list) {
  1178. free(mbstring_globals->script_encoding_list);
  1179. }
  1180. #endif /* ZEND_MULTIBYTE */
  1181. if (mbstring_globals->detect_order_list) {
  1182. free(mbstring_globals->detect_order_list);
  1183. }
  1184. if (mbstring_globals->http_output_conv_mimetypes) {
  1185. _php_mb_free_regex(mbstring_globals->http_output_conv_mimetypes);
  1186. }
  1187. #if HAVE_MBREGEX
  1188. php_mb_regex_globals_free(mbstring_globals->mb_regex_globals TSRMLS_CC);
  1189. #endif
  1190. }
  1191. /* }}} */
  1192. /* {{{ PHP_MINIT_FUNCTION(mbstring) */
  1193. PHP_MINIT_FUNCTION(mbstring)
  1194. {
  1195. __mbfl_allocators = &_php_mb_allocators;
  1196. REGISTER_INI_ENTRIES();
  1197. /* This is a global handler. Should not be set in a per-request handler. */
  1198. sapi_register_treat_data(mbstr_treat_data);
  1199. /* Post handlers are stored in the thread-local context. */
  1200. if (MBSTRG(encoding_translation)) {
  1201. sapi_register_post_entries(mbstr_post_entries TSRMLS_CC);
  1202. }
  1203. REGISTER_LONG_CONSTANT("MB_OVERLOAD_MAIL", MB_OVERLOAD_MAIL, CONST_CS | CONST_PERSISTENT);
  1204. REGISTER_LONG_CONSTANT("MB_OVERLOAD_STRING", MB_OVERLOAD_STRING, CONST_CS | CONST_PERSISTENT);
  1205. REGISTER_LONG_CONSTANT("MB_OVERLOAD_REGEX", MB_OVERLOAD_REGEX, CONST_CS | CONST_PERSISTENT);
  1206. REGISTER_LONG_CONSTANT("MB_CASE_UPPER", PHP_UNICODE_CASE_UPPER, CONST_CS | CONST_PERSISTENT);
  1207. REGISTER_LONG_CONSTANT("MB_CASE_LOWER", PHP_UNICODE_CASE_LOWER, CONST_CS | CONST_PERSISTENT);
  1208. REGISTER_LONG_CONSTANT("MB_CASE_TITLE", PHP_UNICODE_CASE_TITLE, CONST_CS | CONST_PERSISTENT);
  1209. #if HAVE_MBREGEX
  1210. PHP_MINIT(mb_regex) (INIT_FUNC_ARGS_PASSTHRU);
  1211. #endif
  1212. return SUCCESS;
  1213. }
  1214. /* }}} */
  1215. /* {{{ PHP_MSHUTDOWN_FUNCTION(mbstring) */
  1216. PHP_MSHUTDOWN_FUNCTION(mbstring)
  1217. {
  1218. UNREGISTER_INI_ENTRIES();
  1219. #if HAVE_MBREGEX
  1220. PHP_MSHUTDOWN(mb_regex) (INIT_FUNC_ARGS_PASSTHRU);
  1221. #endif
  1222. return SUCCESS;
  1223. }
  1224. /* }}} */
  1225. /* {{{ PHP_RINIT_FUNCTION(mbstring) */
  1226. PHP_RINIT_FUNCTION(mbstring)
  1227. {
  1228. int n;
  1229. enum mbfl_no_encoding *list=NULL, *entry;
  1230. zend_function *func, *orig;
  1231. const struct mb_overload_def *p;
  1232. MBSTRG(current_internal_encoding) = MBSTRG(internal_encoding);
  1233. MBSTRG(current_http_output_encoding) = MBSTRG(http_output_encoding);
  1234. MBSTRG(current_filter_illegal_mode) = MBSTRG(filter_illegal_mode);
  1235. MBSTRG(current_filter_illegal_substchar) = MBSTRG(filter_illegal_substchar);
  1236. MBSTRG(illegalchars) = 0;
  1237. n = 0;
  1238. if (MBSTRG(detect_order_list)) {
  1239. list = MBSTRG(detect_order_list);
  1240. n = MBSTRG(detect_order_list_size);
  1241. }
  1242. if (n <= 0) {
  1243. list = MBSTRG(default_detect_order_list);
  1244. n = MBSTRG(default_detect_order_list_size);
  1245. }
  1246. entry = (enum mbfl_no_encoding *)safe_emalloc(n, sizeof(int), 0);
  1247. MBSTRG(current_detect_order_list) = entry;
  1248. MBSTRG(current_detect_order_list_size) = n;
  1249. while (n > 0) {
  1250. *entry++ = *list++;
  1251. n--;
  1252. }
  1253. /* override original function. */
  1254. if (MBSTRG(func_overload)){
  1255. p = &(mb_ovld[0]);
  1256. while (p->type > 0) {
  1257. if ((MBSTRG(func_overload) & p->type) == p->type &&
  1258. zend_hash_find(EG(function_table), p->save_func,
  1259. strlen(p->save_func)+1, (void **)&orig) != SUCCESS) {
  1260. zend_hash_find(EG(function_table), p->ovld_func, strlen(p->ovld_func)+1 , (void **)&func);
  1261. if (zend_hash_find(EG(function_table), p->orig_func, strlen(p->orig_func)+1, (void **)&orig) != SUCCESS) {
  1262. php_error_docref("ref.mbstring" TSRMLS_CC, E_WARNING, "mbstring couldn't find function %s.", p->orig_func);
  1263. return FAILURE;
  1264. } else {
  1265. zend_hash_add(EG(function_table), p->save_func, strlen(p->save_func)+1, orig, sizeof(zend_function), NULL);
  1266. if (zend_hash_update(EG(function_table), p->orig_func, strlen(p->orig_func)+1, func, sizeof(zend_function),
  1267. NULL) == FAILURE) {
  1268. php_error_docref("ref.mbstring" TSRMLS_CC, E_WARNING, "mbstring couldn't replace function %s.", p->orig_func);
  1269. return FAILURE;
  1270. }
  1271. }
  1272. }
  1273. p++;
  1274. }
  1275. }
  1276. #if HAVE_MBREGEX
  1277. PHP_RINIT(mb_regex) (INIT_FUNC_ARGS_PASSTHRU);
  1278. #endif
  1279. #ifdef ZEND_MULTIBYTE
  1280. zend_multibyte_set_internal_encoding(mbfl_no_encoding2name(MBSTRG(internal_encoding)) TSRMLS_CC);
  1281. php_mb_set_zend_encoding(TSRMLS_C);
  1282. #endif /* ZEND_MULTIBYTE */
  1283. return SUCCESS;
  1284. }
  1285. /* }}} */
  1286. /* {{{ PHP_RSHUTDOWN_FUNCTION(mbstring) */
  1287. PHP_RSHUTDOWN_FUNCTION(mbstring)
  1288. {
  1289. const struct mb_overload_def *p;
  1290. zend_function *orig;
  1291. if (MBSTRG(current_detect_order_list) != NULL) {
  1292. efree(MBSTRG(current_detect_order_list));
  1293. MBSTRG(current_detect_order_list) = NULL;
  1294. MBSTRG(current_detect_order_list_size) = 0;
  1295. }
  1296. if (MBSTRG(outconv) != NULL) {
  1297. MBSTRG(illegalchars) += mbfl_buffer_illegalchars(MBSTRG(outconv));
  1298. mbfl_buffer_converter_delete(MBSTRG(outconv));
  1299. MBSTRG(outconv) = NULL;
  1300. }
  1301. /* clear http input identification. */
  1302. MBSTRG(http_input_identify) = mbfl_no_encoding_invalid;
  1303. MBSTRG(http_input_identify_post) = mbfl_no_encoding_invalid;
  1304. MBSTRG(http_input_identify_get) = mbfl_no_encoding_invalid;
  1305. MBSTRG(http_input_identify_cookie) = mbfl_no_encoding_invalid;
  1306. MBSTRG(http_input_identify_string) = mbfl_no_encoding_invalid;
  1307. /* clear overloaded function. */
  1308. if (MBSTRG(func_overload)){
  1309. p = &(mb_ovld[0]);
  1310. while (p->type > 0) {
  1311. if ((MBSTRG(func_overload) & p->type) == p->type &&
  1312. zend_hash_find(EG(function_table), p->save_func,
  1313. strlen(p->save_func)+1, (void **)&orig) == SUCCESS) {
  1314. zend_hash_update(EG(function_table), p->orig_func, strlen(p->orig_func)+1, orig, sizeof(zend_function), NULL);
  1315. zend_hash_del(EG(function_table), p->save_func, strlen(p->save_func)+1);
  1316. }
  1317. p++;
  1318. }
  1319. }
  1320. #if HAVE_MBREGEX
  1321. PHP_RSHUTDOWN(mb_regex) (INIT_FUNC_ARGS_PASSTHRU);
  1322. #endif
  1323. return SUCCESS;
  1324. }
  1325. /* }}} */
  1326. /* {{{ PHP_MINFO_FUNCTION(mbstring) */
  1327. PHP_MINFO_FUNCTION(mbstring)
  1328. {
  1329. php_info_print_table_start();
  1330. php_info_print_table_row(2, "Multibyte Support", "enabled");
  1331. php_info_print_table_row(2, "Multibyte string engine", "libmbfl");
  1332. php_info_print_table_row(2, "HTTP input encoding translation", MBSTRG(encoding_translation) ? "enabled": "disabled");
  1333. php_info_print_table_end();
  1334. php_info_print_table_start();
  1335. php_info_print_table_header(1, "mbstring extension makes use of \"streamable kanji code filter and converter\", which is distributed under the GNU Lesser General Public License version 2.1.");
  1336. php_info_print_table_end();
  1337. #if HAVE_MBREGEX
  1338. PHP_MINFO(mb_regex)(ZEND_MODULE_INFO_FUNC_ARGS_PASSTHRU);
  1339. #endif
  1340. DISPLAY_INI_ENTRIES();
  1341. }
  1342. /* }}} */
  1343. /* {{{ proto string mb_language([string language])
  1344. Sets the current language or Returns the current language as a string */
  1345. PHP_FUNCTION(mb_language)
  1346. {
  1347. char *name = NULL;
  1348. int name_len = 0;
  1349. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len) == FAILURE) {
  1350. return;
  1351. }
  1352. if (name == NULL) {
  1353. RETVAL_STRING((char *)mbfl_no_language2name(MBSTRG(language)), 1);
  1354. } else {
  1355. if (FAILURE == zend_alter_ini_entry(
  1356. "mbstring.language", sizeof("mbstring.language"),
  1357. name, name_len, PHP_INI_USER, PHP_INI_STAGE_RUNTIME)) {
  1358. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown language \"%s\"", name);
  1359. RETVAL_FALSE;
  1360. } else {
  1361. RETVAL_TRUE;
  1362. }
  1363. }
  1364. }
  1365. /* }}} */
  1366. /* {{{ proto string mb_internal_encoding([string encoding])
  1367. Sets the current internal encoding or Returns the current internal encoding as a string */
  1368. PHP_FUNCTION(mb_internal_encoding)
  1369. {
  1370. char *name = NULL;
  1371. int name_len;
  1372. enum mbfl_no_encoding no_encoding;
  1373. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &name, &name_len) == FAILURE) {
  1374. RETURN_FALSE;
  1375. }
  1376. if (name == NULL) {
  1377. name = (char *)mbfl_no_encoding2name(MBSTRG(current_internal_encoding));
  1378. if (name != NULL) {
  1379. RETURN_STRING(name, 1);
  1380. } else {
  1381. RETURN_FALSE;
  1382. }
  1383. } else {
  1384. no_encoding = mbfl_name2no_encoding(name);
  1385. if (no_encoding == mbfl_no_encoding_invalid) {
  1386. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown encoding \"%s\"", name);
  1387. RETURN_FALSE;
  1388. } else {
  1389. MBSTRG(current_internal_encoding) = no_encoding;
  1390. #ifdef ZEND_MULTIBYTE
  1391. /* TODO: make independent from mbstring.encoding_translation? */
  1392. if (MBSTRG(encoding_translation)) {
  1393. zend_multibyte_set_internal_encoding(name TSRMLS_CC);
  1394. }
  1395. #endif /* ZEND_MULTIBYTE */
  1396. RETURN_TRUE;
  1397. }
  1398. }
  1399. }
  1400. /* }}} */
  1401. /* {{{ proto mixed mb_http_input([string type])
  1402. Returns the input encoding */
  1403. PHP_FUNCTION(mb_http_input)
  1404. {
  1405. char *typ = NULL;
  1406. int typ_len;
  1407. int retname, n;
  1408. char *name, *list, *temp;
  1409. enum mbfl_no_encoding *entry;
  1410. enum mbfl_no_encoding result = mbfl_no_encoding_invalid;
  1411. retname = 1;
  1412. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &typ, &typ_len) == FAILURE) {
  1413. RETURN_FALSE;
  1414. }
  1415. if (typ == NULL) {
  1416. result = MBSTRG(http_input_identify);
  1417. } else {
  1418. switch (*typ) {
  1419. case 'G':
  1420. case 'g':
  1421. result = MBSTRG(http_input_identify_get);
  1422. break;
  1423. case 'P':
  1424. case 'p':
  1425. result = MBSTRG(http_input_identify_post);
  1426. break;
  1427. case 'C':
  1428. case 'c':
  1429. result = MBSTRG(http_input_identify_cookie);
  1430. break;
  1431. case 'S':
  1432. case 's':
  1433. result = MBSTRG(http_input_identify_string);
  1434. break;
  1435. case 'I':
  1436. case 'i':
  1437. array_init(return_value);
  1438. entry = MBSTRG(http_input_list);
  1439. n = MBSTRG(http_input_list_size);
  1440. while (n > 0) {
  1441. name = (char *)mbfl_no_encoding2name(*entry);
  1442. if (name) {
  1443. add_next_index_string(return_value, name, 1);
  1444. }
  1445. entry++;
  1446. n--;
  1447. }
  1448. retname = 0;
  1449. break;
  1450. case 'L':
  1451. case 'l':
  1452. entry = MBSTRG(http_input_list);
  1453. n = MBSTRG(http_input_list_size);
  1454. list = NULL;
  1455. while (n > 0) {
  1456. name = (char *)mbfl_no_encoding2name(*entry);
  1457. if (name) {
  1458. if (list) {
  1459. temp = list;
  1460. spprintf(&list, 0, "%s,%s", temp, name);
  1461. efree(temp);
  1462. if (!list) {
  1463. break;
  1464. }
  1465. } else {
  1466. list = estrdup(name);
  1467. }
  1468. }
  1469. entry++;
  1470. n--;
  1471. }
  1472. if (!list) {
  1473. RETURN_FALSE;
  1474. }
  1475. RETVAL_STRING(list, 0);
  1476. retname = 0;
  1477. break;
  1478. default:
  1479. result = MBSTRG(http_input_identify);
  1480. break;
  1481. }
  1482. }
  1483. if (retname) {
  1484. if (result != mbfl_no_encoding_invalid &&

Large files files are truncated, but you can click here to view the full file