Coverage Report

Created: 2025-06-13 06:43

/src/php-src/Zend/zend_multibyte.c
Line
Count
Source (jump to first uncovered line)
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
20
#include "zend.h"
21
#include "zend_compile.h"
22
#include "zend_operators.h"
23
#include "zend_multibyte.h"
24
#include "zend_ini.h"
25
26
static const zend_encoding *dummy_encoding_fetcher(const char *encoding_name)
27
12.5k
{
28
12.5k
  return NULL;
29
12.5k
}
30
31
static const char *dummy_encoding_name_getter(const zend_encoding *encoding)
32
0
{
33
0
  return (const char*)encoding;
34
0
}
35
36
static bool dummy_encoding_lexer_compatibility_checker(const zend_encoding *encoding)
37
0
{
38
0
  return 0;
39
0
}
40
41
static const zend_encoding *dummy_encoding_detector(const unsigned char *string, size_t length, const zend_encoding **list, size_t list_size)
42
0
{
43
0
  return NULL;
44
0
}
45
46
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)
47
4.18k
{
48
4.18k
  return (size_t)-1;
49
4.18k
}
50
51
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)
52
80
{
53
80
  *return_list = pemalloc(0, persistent);
54
80
  *return_size = 0;
55
80
  return SUCCESS;
56
80
}
57
58
static const zend_encoding *dummy_internal_encoding_getter(void)
59
0
{
60
0
  return NULL;
61
0
}
62
63
static zend_result dummy_internal_encoding_setter(const zend_encoding *encoding)
64
0
{
65
0
  return FAILURE;
66
0
}
67
68
static zend_multibyte_functions multibyte_functions_dummy;
69
static zend_multibyte_functions multibyte_functions = {
70
  NULL,
71
  dummy_encoding_fetcher,
72
  dummy_encoding_name_getter,
73
  dummy_encoding_lexer_compatibility_checker,
74
  dummy_encoding_detector,
75
  dummy_encoding_converter,
76
  dummy_encoding_list_parser,
77
  dummy_internal_encoding_getter,
78
  dummy_internal_encoding_setter
79
};
80
81
ZEND_API const zend_encoding *zend_multibyte_encoding_utf32be = (const zend_encoding*)"UTF-32BE";
82
ZEND_API const zend_encoding *zend_multibyte_encoding_utf32le = (const zend_encoding*)"UTF-32LE";
83
ZEND_API const zend_encoding *zend_multibyte_encoding_utf16be = (const zend_encoding*)"UTF-16BE";
84
ZEND_API const zend_encoding *zend_multibyte_encoding_utf16le = (const zend_encoding*)"UTF-32LE";
85
ZEND_API const zend_encoding *zend_multibyte_encoding_utf8 = (const zend_encoding*)"UTF-8";
86
87
ZEND_API zend_result zend_multibyte_set_functions(const zend_multibyte_functions *functions)
88
0
{
89
0
  zend_multibyte_encoding_utf32be = functions->encoding_fetcher("UTF-32BE");
90
0
  if (!zend_multibyte_encoding_utf32be) {
91
0
    return FAILURE;
92
0
  }
93
0
  zend_multibyte_encoding_utf32le = functions->encoding_fetcher("UTF-32LE");
94
0
  if (!zend_multibyte_encoding_utf32le) {
95
0
    return FAILURE;
96
0
  }
97
0
  zend_multibyte_encoding_utf16be = functions->encoding_fetcher("UTF-16BE");
98
0
  if (!zend_multibyte_encoding_utf16be) {
99
0
    return FAILURE;
100
0
  }
101
0
  zend_multibyte_encoding_utf16le = functions->encoding_fetcher("UTF-16LE");
102
0
  if (!zend_multibyte_encoding_utf16le) {
103
0
    return FAILURE;
104
0
  }
105
0
  zend_multibyte_encoding_utf8 = functions->encoding_fetcher("UTF-8");
106
0
  if (!zend_multibyte_encoding_utf8) {
107
0
    return FAILURE;
108
0
  }
109
110
0
  multibyte_functions_dummy = multibyte_functions;
111
0
  multibyte_functions = *functions;
112
113
  /* As zend_multibyte_set_functions() gets called after ini settings were
114
   * populated, we need to reinitialize script_encoding here.
115
   */
116
0
  {
117
0
    const char *value = zend_ini_string("zend.script_encoding", sizeof("zend.script_encoding") - 1, 0);
118
0
    zend_multibyte_set_script_encoding_by_string(value, strlen(value));
119
0
  }
120
0
  return SUCCESS;
121
0
}
122
123
ZEND_API void zend_multibyte_restore_functions(void)
124
0
{
125
0
  multibyte_functions = multibyte_functions_dummy;
126
0
}
127
128
ZEND_API const zend_multibyte_functions *zend_multibyte_get_functions(void)
129
5
{
130
5
  return multibyte_functions.provider_name ? &multibyte_functions: NULL;
131
5
}
132
133
ZEND_API const zend_encoding *zend_multibyte_fetch_encoding(const char *name)
134
12.5k
{
135
12.5k
  return multibyte_functions.encoding_fetcher(name);
136
12.5k
}
137
138
ZEND_API const char *zend_multibyte_get_encoding_name(const zend_encoding *encoding)
139
0
{
140
0
  return multibyte_functions.encoding_name_getter(encoding);
141
0
}
142
143
ZEND_API int zend_multibyte_check_lexer_compatibility(const zend_encoding *encoding)
144
0
{
145
0
  return multibyte_functions.lexer_compatibility_checker(encoding);
146
0
}
147
148
ZEND_API const zend_encoding *zend_multibyte_encoding_detector(const unsigned char *string, size_t length, const zend_encoding **list, size_t list_size)
149
0
{
150
0
  return multibyte_functions.encoding_detector(string, length, list, list_size);
151
0
}
152
153
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)
154
4.18k
{
155
4.18k
  return multibyte_functions.encoding_converter(to, to_length, from, from_length, encoding_to, encoding_from);
156
4.18k
}
157
158
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)
159
80
{
160
80
  return multibyte_functions.encoding_list_parser(encoding_list, encoding_list_len, return_list, return_size, persistent);
161
80
}
162
163
ZEND_API const zend_encoding *zend_multibyte_get_internal_encoding(void)
164
0
{
165
0
  return multibyte_functions.internal_encoding_getter();
166
0
}
167
168
ZEND_API const zend_encoding *zend_multibyte_get_script_encoding(void)
169
0
{
170
0
  return LANG_SCNG(script_encoding);
171
0
}
172
173
ZEND_API zend_result zend_multibyte_set_script_encoding(const zend_encoding **encoding_list, size_t encoding_list_size)
174
0
{
175
0
  if (CG(script_encoding_list)) {
176
0
    free((char*)CG(script_encoding_list));
177
0
  }
178
0
  CG(script_encoding_list) = encoding_list;
179
0
  CG(script_encoding_list_size) = encoding_list_size;
180
0
  return SUCCESS;
181
0
}
182
183
ZEND_API zend_result zend_multibyte_set_internal_encoding(const zend_encoding *encoding)
184
0
{
185
0
  return multibyte_functions.internal_encoding_setter(encoding);
186
0
}
187
188
ZEND_API zend_result zend_multibyte_set_script_encoding_by_string(const char *new_value, size_t new_value_length)
189
0
{
190
0
  const zend_encoding **list = 0;
191
0
  size_t size = 0;
192
193
0
  if (!new_value) {
194
0
    zend_multibyte_set_script_encoding(NULL, 0);
195
0
    return SUCCESS;
196
0
  }
197
198
0
  if (FAILURE == zend_multibyte_parse_encoding_list(new_value, new_value_length, &list, &size, 1)) {
199
0
    return FAILURE;
200
0
  }
201
202
0
  if (size == 0) {
203
0
    pefree((void*)list, 1);
204
0
    return FAILURE;
205
0
  }
206
207
0
  if (FAILURE == zend_multibyte_set_script_encoding(list, size)) {
208
0
    return FAILURE;
209
0
  }
210
211
0
  return SUCCESS;
212
0
}