zend_multibyte.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Zend Engine |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 2.00 of the Zend license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at |
  10. | http://www.zend.com/license/2_00.txt. |
  11. | If you did not receive a copy of the Zend license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@zend.com so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Masaki Fujimoto <fujimoto@php.net> |
  16. | Rui Hirokawa <hirokawa@php.net> |
  17. +----------------------------------------------------------------------+
  18. */
  19. #include "zend.h"
  20. #include "zend_compile.h"
  21. #include "zend_operators.h"
  22. #include "zend_multibyte.h"
  23. #include "zend_ini.h"
  24. static const zend_encoding *dummy_encoding_fetcher(const char *encoding_name)
  25. {
  26. return NULL;
  27. }
  28. static const char *dummy_encoding_name_getter(const zend_encoding *encoding)
  29. {
  30. return (const char*)encoding;
  31. }
  32. static bool dummy_encoding_lexer_compatibility_checker(const zend_encoding *encoding)
  33. {
  34. return 0;
  35. }
  36. static const zend_encoding *dummy_encoding_detector(const unsigned char *string, size_t length, const zend_encoding **list, size_t list_size)
  37. {
  38. return NULL;
  39. }
  40. static size_t dummy_encoding_converter(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length, const zend_encoding *encoding_to, const zend_encoding *encoding_from)
  41. {
  42. return (size_t)-1;
  43. }
  44. static zend_result dummy_encoding_list_parser(const char *encoding_list, size_t encoding_list_len, const zend_encoding ***return_list, size_t *return_size, bool persistent)
  45. {
  46. *return_list = pemalloc(0, persistent);
  47. *return_size = 0;
  48. return SUCCESS;
  49. }
  50. static const zend_encoding *dummy_internal_encoding_getter(void)
  51. {
  52. return NULL;
  53. }
  54. static zend_result dummy_internal_encoding_setter(const zend_encoding *encoding)
  55. {
  56. return FAILURE;
  57. }
  58. static zend_multibyte_functions multibyte_functions_dummy;
  59. static zend_multibyte_functions multibyte_functions = {
  60. NULL,
  61. dummy_encoding_fetcher,
  62. dummy_encoding_name_getter,
  63. dummy_encoding_lexer_compatibility_checker,
  64. dummy_encoding_detector,
  65. dummy_encoding_converter,
  66. dummy_encoding_list_parser,
  67. dummy_internal_encoding_getter,
  68. dummy_internal_encoding_setter
  69. };
  70. ZEND_API const zend_encoding *zend_multibyte_encoding_utf32be = (const zend_encoding*)"UTF-32BE";
  71. ZEND_API const zend_encoding *zend_multibyte_encoding_utf32le = (const zend_encoding*)"UTF-32LE";
  72. ZEND_API const zend_encoding *zend_multibyte_encoding_utf16be = (const zend_encoding*)"UTF-16BE";
  73. ZEND_API const zend_encoding *zend_multibyte_encoding_utf16le = (const zend_encoding*)"UTF-32LE";
  74. ZEND_API const zend_encoding *zend_multibyte_encoding_utf8 = (const zend_encoding*)"UTF-8";
  75. ZEND_API zend_result zend_multibyte_set_functions(const zend_multibyte_functions *functions)
  76. {
  77. zend_multibyte_encoding_utf32be = functions->encoding_fetcher("UTF-32BE");
  78. if (!zend_multibyte_encoding_utf32be) {
  79. return FAILURE;
  80. }
  81. zend_multibyte_encoding_utf32le = functions->encoding_fetcher("UTF-32LE");
  82. if (!zend_multibyte_encoding_utf32le) {
  83. return FAILURE;
  84. }
  85. zend_multibyte_encoding_utf16be = functions->encoding_fetcher("UTF-16BE");
  86. if (!zend_multibyte_encoding_utf16be) {
  87. return FAILURE;
  88. }
  89. zend_multibyte_encoding_utf16le = functions->encoding_fetcher("UTF-16LE");
  90. if (!zend_multibyte_encoding_utf16le) {
  91. return FAILURE;
  92. }
  93. zend_multibyte_encoding_utf8 = functions->encoding_fetcher("UTF-8");
  94. if (!zend_multibyte_encoding_utf8) {
  95. return FAILURE;
  96. }
  97. multibyte_functions_dummy = multibyte_functions;
  98. multibyte_functions = *functions;
  99. /* As zend_multibyte_set_functions() gets called after ini settings were
  100. * populated, we need to reinitialize script_encoding here.
  101. */
  102. {
  103. const char *value = zend_ini_string("zend.script_encoding", sizeof("zend.script_encoding") - 1, 0);
  104. zend_multibyte_set_script_encoding_by_string(value, strlen(value));
  105. }
  106. return SUCCESS;
  107. }
  108. ZEND_API void zend_multibyte_restore_functions(void)
  109. {
  110. multibyte_functions = multibyte_functions_dummy;
  111. }
  112. ZEND_API const zend_multibyte_functions *zend_multibyte_get_functions(void)
  113. {
  114. return multibyte_functions.provider_name ? &multibyte_functions: NULL;
  115. }
  116. ZEND_API const zend_encoding *zend_multibyte_fetch_encoding(const char *name)
  117. {
  118. return multibyte_functions.encoding_fetcher(name);
  119. }
  120. ZEND_API const char *zend_multibyte_get_encoding_name(const zend_encoding *encoding)
  121. {
  122. return multibyte_functions.encoding_name_getter(encoding);
  123. }
  124. ZEND_API int zend_multibyte_check_lexer_compatibility(const zend_encoding *encoding)
  125. {
  126. return multibyte_functions.lexer_compatibility_checker(encoding);
  127. }
  128. ZEND_API const zend_encoding *zend_multibyte_encoding_detector(const unsigned char *string, size_t length, const zend_encoding **list, size_t list_size)
  129. {
  130. return multibyte_functions.encoding_detector(string, length, list, list_size);
  131. }
  132. ZEND_API size_t zend_multibyte_encoding_converter(unsigned char **to, size_t *to_length, const unsigned char *from, size_t from_length, const zend_encoding *encoding_to, const zend_encoding *encoding_from)
  133. {
  134. return multibyte_functions.encoding_converter(to, to_length, from, from_length, encoding_to, encoding_from);
  135. }
  136. ZEND_API zend_result zend_multibyte_parse_encoding_list(const char *encoding_list, size_t encoding_list_len, const zend_encoding ***return_list, size_t *return_size, bool persistent)
  137. {
  138. return multibyte_functions.encoding_list_parser(encoding_list, encoding_list_len, return_list, return_size, persistent);
  139. }
  140. ZEND_API const zend_encoding *zend_multibyte_get_internal_encoding(void)
  141. {
  142. return multibyte_functions.internal_encoding_getter();
  143. }
  144. ZEND_API const zend_encoding *zend_multibyte_get_script_encoding(void)
  145. {
  146. return LANG_SCNG(script_encoding);
  147. }
  148. ZEND_API int zend_multibyte_set_script_encoding(const zend_encoding **encoding_list, size_t encoding_list_size)
  149. {
  150. if (CG(script_encoding_list)) {
  151. free((char*)CG(script_encoding_list));
  152. }
  153. CG(script_encoding_list) = encoding_list;
  154. CG(script_encoding_list_size) = encoding_list_size;
  155. return SUCCESS;
  156. }
  157. ZEND_API zend_result zend_multibyte_set_internal_encoding(const zend_encoding *encoding)
  158. {
  159. return multibyte_functions.internal_encoding_setter(encoding);
  160. }
  161. ZEND_API zend_result zend_multibyte_set_script_encoding_by_string(const char *new_value, size_t new_value_length)
  162. {
  163. const zend_encoding **list = 0;
  164. size_t size = 0;
  165. if (!new_value) {
  166. zend_multibyte_set_script_encoding(NULL, 0);
  167. return SUCCESS;
  168. }
  169. if (FAILURE == zend_multibyte_parse_encoding_list(new_value, new_value_length, &list, &size, 1)) {
  170. return FAILURE;
  171. }
  172. if (size == 0) {
  173. pefree((void*)list, 1);
  174. return FAILURE;
  175. }
  176. if (FAILURE == zend_multibyte_set_script_encoding(list, size)) {
  177. return FAILURE;
  178. }
  179. return SUCCESS;
  180. }