/src/postgres/src/backend/utils/mb/mbutils.c
Line | Count | Source |
1 | | /*------------------------------------------------------------------------- |
2 | | * |
3 | | * mbutils.c |
4 | | * This file contains functions for encoding conversion. |
5 | | * |
6 | | * The string-conversion functions in this file share some API quirks. |
7 | | * Note the following: |
8 | | * |
9 | | * The functions return a palloc'd, null-terminated string if conversion |
10 | | * is required. However, if no conversion is performed, the given source |
11 | | * string pointer is returned as-is. |
12 | | * |
13 | | * Although the presence of a length argument means that callers can pass |
14 | | * non-null-terminated strings, care is required because the same string |
15 | | * will be passed back if no conversion occurs. Such callers *must* check |
16 | | * whether result == src and handle that case differently. |
17 | | * |
18 | | * If the source and destination encodings are the same, the source string |
19 | | * is returned without any verification; it's assumed to be valid data. |
20 | | * If that might not be the case, the caller is responsible for validating |
21 | | * the string using a separate call to pg_verify_mbstr(). Whenever the |
22 | | * source and destination encodings are different, the functions ensure that |
23 | | * the result is validly encoded according to the destination encoding. |
24 | | * |
25 | | * |
26 | | * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group |
27 | | * Portions Copyright (c) 1994, Regents of the University of California |
28 | | * |
29 | | * |
30 | | * IDENTIFICATION |
31 | | * src/backend/utils/mb/mbutils.c |
32 | | * |
33 | | *------------------------------------------------------------------------- |
34 | | */ |
35 | | #include "postgres.h" |
36 | | |
37 | | #include "access/xact.h" |
38 | | #include "catalog/namespace.h" |
39 | | #include "mb/pg_wchar.h" |
40 | | #include "utils/fmgrprotos.h" |
41 | | #include "utils/memdebug.h" |
42 | | #include "utils/memutils.h" |
43 | | #include "utils/relcache.h" |
44 | | #include "varatt.h" |
45 | | |
46 | | /* |
47 | | * We maintain a simple linked list caching the fmgr lookup info for the |
48 | | * currently selected conversion functions, as well as any that have been |
49 | | * selected previously in the current session. (We remember previous |
50 | | * settings because we must be able to restore a previous setting during |
51 | | * transaction rollback, without doing any fresh catalog accesses.) |
52 | | * |
53 | | * Since we'll never release this data, we just keep it in TopMemoryContext. |
54 | | */ |
55 | | typedef struct ConvProcInfo |
56 | | { |
57 | | int s_encoding; /* server and client encoding IDs */ |
58 | | int c_encoding; |
59 | | FmgrInfo to_server_info; /* lookup info for conversion procs */ |
60 | | FmgrInfo to_client_info; |
61 | | } ConvProcInfo; |
62 | | |
63 | | static List *ConvProcList = NIL; /* List of ConvProcInfo */ |
64 | | |
65 | | /* |
66 | | * These variables point to the currently active conversion functions, |
67 | | * or are NULL when no conversion is needed. |
68 | | */ |
69 | | static FmgrInfo *ToServerConvProc = NULL; |
70 | | static FmgrInfo *ToClientConvProc = NULL; |
71 | | |
72 | | /* |
73 | | * This variable stores the conversion function to convert from UTF-8 |
74 | | * to the server encoding. It's NULL if the server encoding *is* UTF-8, |
75 | | * or if we lack a conversion function for this. |
76 | | */ |
77 | | static FmgrInfo *Utf8ToServerConvProc = NULL; |
78 | | |
79 | | /* |
80 | | * These variables track the currently-selected encodings. |
81 | | */ |
82 | | static const pg_enc2name *ClientEncoding = &pg_enc2name_tbl[PG_SQL_ASCII]; |
83 | | static const pg_enc2name *DatabaseEncoding = &pg_enc2name_tbl[PG_SQL_ASCII]; |
84 | | static const pg_enc2name *MessageEncoding = &pg_enc2name_tbl[PG_SQL_ASCII]; |
85 | | |
86 | | /* |
87 | | * During backend startup we can't set client encoding because we (a) |
88 | | * can't look up the conversion functions, and (b) may not know the database |
89 | | * encoding yet either. So SetClientEncoding() just accepts anything and |
90 | | * remembers it for InitializeClientEncoding() to apply later. |
91 | | */ |
92 | | static bool backend_startup_complete = false; |
93 | | static int pending_client_encoding = PG_SQL_ASCII; |
94 | | |
95 | | |
96 | | /* Internal functions */ |
97 | | static char *perform_default_encoding_conversion(const char *src, |
98 | | int len, bool is_client_to_server); |
99 | | static int cliplen(const char *str, int len, int limit); |
100 | | |
101 | | pg_noreturn |
102 | | static void report_invalid_encoding_int(int encoding, const char *mbstr, |
103 | | int mblen, int len); |
104 | | |
105 | | pg_noreturn |
106 | | static void report_invalid_encoding_db(const char *mbstr, int mblen, int len); |
107 | | |
108 | | |
109 | | /* |
110 | | * Prepare for a future call to SetClientEncoding. Success should mean |
111 | | * that SetClientEncoding is guaranteed to succeed for this encoding request. |
112 | | * |
113 | | * (But note that success before backend_startup_complete does not guarantee |
114 | | * success after ...) |
115 | | * |
116 | | * Returns 0 if okay, -1 if not (bad encoding or can't support conversion) |
117 | | */ |
118 | | int |
119 | | PrepareClientEncoding(int encoding) |
120 | 2 | { |
121 | 2 | int current_server_encoding; |
122 | 2 | ListCell *lc; |
123 | | |
124 | 2 | if (!PG_VALID_FE_ENCODING(encoding)) |
125 | 0 | return -1; |
126 | | |
127 | | /* Can't do anything during startup, per notes above */ |
128 | 2 | if (!backend_startup_complete) |
129 | 2 | return 0; |
130 | | |
131 | 0 | current_server_encoding = GetDatabaseEncoding(); |
132 | | |
133 | | /* |
134 | | * Check for cases that require no conversion function. |
135 | | */ |
136 | 0 | if (current_server_encoding == encoding || |
137 | 0 | current_server_encoding == PG_SQL_ASCII || |
138 | 0 | encoding == PG_SQL_ASCII) |
139 | 0 | return 0; |
140 | | |
141 | 0 | if (IsTransactionState()) |
142 | 0 | { |
143 | | /* |
144 | | * If we're in a live transaction, it's safe to access the catalogs, |
145 | | * so look up the functions. We repeat the lookup even if the info is |
146 | | * already cached, so that we can react to changes in the contents of |
147 | | * pg_conversion. |
148 | | */ |
149 | 0 | Oid to_server_proc, |
150 | 0 | to_client_proc; |
151 | 0 | ConvProcInfo *convinfo; |
152 | 0 | MemoryContext oldcontext; |
153 | |
|
154 | 0 | to_server_proc = FindDefaultConversionProc(encoding, |
155 | 0 | current_server_encoding); |
156 | 0 | if (!OidIsValid(to_server_proc)) |
157 | 0 | return -1; |
158 | 0 | to_client_proc = FindDefaultConversionProc(current_server_encoding, |
159 | 0 | encoding); |
160 | 0 | if (!OidIsValid(to_client_proc)) |
161 | 0 | return -1; |
162 | | |
163 | | /* |
164 | | * Load the fmgr info into TopMemoryContext (could still fail here) |
165 | | */ |
166 | 0 | convinfo = (ConvProcInfo *) MemoryContextAlloc(TopMemoryContext, |
167 | 0 | sizeof(ConvProcInfo)); |
168 | 0 | convinfo->s_encoding = current_server_encoding; |
169 | 0 | convinfo->c_encoding = encoding; |
170 | 0 | fmgr_info_cxt(to_server_proc, &convinfo->to_server_info, |
171 | 0 | TopMemoryContext); |
172 | 0 | fmgr_info_cxt(to_client_proc, &convinfo->to_client_info, |
173 | 0 | TopMemoryContext); |
174 | | |
175 | | /* Attach new info to head of list */ |
176 | 0 | oldcontext = MemoryContextSwitchTo(TopMemoryContext); |
177 | 0 | ConvProcList = lcons(convinfo, ConvProcList); |
178 | 0 | MemoryContextSwitchTo(oldcontext); |
179 | | |
180 | | /* |
181 | | * We cannot yet remove any older entry for the same encoding pair, |
182 | | * since it could still be in use. SetClientEncoding will clean up. |
183 | | */ |
184 | |
|
185 | 0 | return 0; /* success */ |
186 | 0 | } |
187 | 0 | else |
188 | 0 | { |
189 | | /* |
190 | | * If we're not in a live transaction, the only thing we can do is |
191 | | * restore a previous setting using the cache. This covers all |
192 | | * transaction-rollback cases. The only case it might not work for is |
193 | | * trying to change client_encoding on the fly by editing |
194 | | * postgresql.conf and SIGHUP'ing. Which would probably be a stupid |
195 | | * thing to do anyway. |
196 | | */ |
197 | 0 | foreach(lc, ConvProcList) |
198 | 0 | { |
199 | 0 | ConvProcInfo *oldinfo = (ConvProcInfo *) lfirst(lc); |
200 | |
|
201 | 0 | if (oldinfo->s_encoding == current_server_encoding && |
202 | 0 | oldinfo->c_encoding == encoding) |
203 | 0 | return 0; |
204 | 0 | } |
205 | | |
206 | 0 | return -1; /* it's not cached, so fail */ |
207 | 0 | } |
208 | 0 | } |
209 | | |
210 | | /* |
211 | | * Set the active client encoding and set up the conversion-function pointers. |
212 | | * PrepareClientEncoding should have been called previously for this encoding. |
213 | | * |
214 | | * Returns 0 if okay, -1 if not (bad encoding or can't support conversion) |
215 | | */ |
216 | | int |
217 | | SetClientEncoding(int encoding) |
218 | 2 | { |
219 | 2 | int current_server_encoding; |
220 | 2 | bool found; |
221 | 2 | ListCell *lc; |
222 | | |
223 | 2 | if (!PG_VALID_FE_ENCODING(encoding)) |
224 | 0 | return -1; |
225 | | |
226 | | /* Can't do anything during startup, per notes above */ |
227 | 2 | if (!backend_startup_complete) |
228 | 2 | { |
229 | 2 | pending_client_encoding = encoding; |
230 | 2 | return 0; |
231 | 2 | } |
232 | | |
233 | 0 | current_server_encoding = GetDatabaseEncoding(); |
234 | | |
235 | | /* |
236 | | * Check for cases that require no conversion function. |
237 | | */ |
238 | 0 | if (current_server_encoding == encoding || |
239 | 0 | current_server_encoding == PG_SQL_ASCII || |
240 | 0 | encoding == PG_SQL_ASCII) |
241 | 0 | { |
242 | 0 | ClientEncoding = &pg_enc2name_tbl[encoding]; |
243 | 0 | ToServerConvProc = NULL; |
244 | 0 | ToClientConvProc = NULL; |
245 | 0 | return 0; |
246 | 0 | } |
247 | | |
248 | | /* |
249 | | * Search the cache for the entry previously prepared by |
250 | | * PrepareClientEncoding; if there isn't one, we lose. While at it, |
251 | | * release any duplicate entries so that repeated Prepare/Set cycles don't |
252 | | * leak memory. |
253 | | */ |
254 | 0 | found = false; |
255 | 0 | foreach(lc, ConvProcList) |
256 | 0 | { |
257 | 0 | ConvProcInfo *convinfo = (ConvProcInfo *) lfirst(lc); |
258 | |
|
259 | 0 | if (convinfo->s_encoding == current_server_encoding && |
260 | 0 | convinfo->c_encoding == encoding) |
261 | 0 | { |
262 | 0 | if (!found) |
263 | 0 | { |
264 | | /* Found newest entry, so set up */ |
265 | 0 | ClientEncoding = &pg_enc2name_tbl[encoding]; |
266 | 0 | ToServerConvProc = &convinfo->to_server_info; |
267 | 0 | ToClientConvProc = &convinfo->to_client_info; |
268 | 0 | found = true; |
269 | 0 | } |
270 | 0 | else |
271 | 0 | { |
272 | | /* Duplicate entry, release it */ |
273 | 0 | ConvProcList = foreach_delete_current(ConvProcList, lc); |
274 | 0 | pfree(convinfo); |
275 | 0 | } |
276 | 0 | } |
277 | 0 | } |
278 | |
|
279 | 0 | if (found) |
280 | 0 | return 0; /* success */ |
281 | 0 | else |
282 | 0 | return -1; /* it's not cached, so fail */ |
283 | 0 | } |
284 | | |
285 | | /* |
286 | | * Initialize client encoding conversions. |
287 | | * Called from InitPostgres() once during backend startup. |
288 | | */ |
289 | | void |
290 | | InitializeClientEncoding(void) |
291 | 0 | { |
292 | 0 | int current_server_encoding; |
293 | |
|
294 | 0 | Assert(!backend_startup_complete); |
295 | 0 | backend_startup_complete = true; |
296 | |
|
297 | 0 | if (PrepareClientEncoding(pending_client_encoding) < 0 || |
298 | 0 | SetClientEncoding(pending_client_encoding) < 0) |
299 | 0 | { |
300 | | /* |
301 | | * Oops, the requested conversion is not available. We couldn't fail |
302 | | * before, but we can now. |
303 | | */ |
304 | 0 | ereport(FATAL, |
305 | 0 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
306 | 0 | errmsg("conversion between %s and %s is not supported", |
307 | 0 | pg_enc2name_tbl[pending_client_encoding].name, |
308 | 0 | GetDatabaseEncodingName()))); |
309 | 0 | } |
310 | | |
311 | | /* |
312 | | * Also look up the UTF8-to-server conversion function if needed. Since |
313 | | * the server encoding is fixed within any one backend process, we don't |
314 | | * have to do this more than once. |
315 | | */ |
316 | 0 | current_server_encoding = GetDatabaseEncoding(); |
317 | 0 | if (current_server_encoding != PG_UTF8 && |
318 | 0 | current_server_encoding != PG_SQL_ASCII) |
319 | 0 | { |
320 | 0 | Oid utf8_to_server_proc; |
321 | |
|
322 | 0 | AssertCouldGetRelation(); |
323 | 0 | utf8_to_server_proc = |
324 | 0 | FindDefaultConversionProc(PG_UTF8, |
325 | 0 | current_server_encoding); |
326 | | /* If there's no such conversion, just leave the pointer as NULL */ |
327 | 0 | if (OidIsValid(utf8_to_server_proc)) |
328 | 0 | { |
329 | 0 | FmgrInfo *finfo; |
330 | |
|
331 | 0 | finfo = (FmgrInfo *) MemoryContextAlloc(TopMemoryContext, |
332 | 0 | sizeof(FmgrInfo)); |
333 | 0 | fmgr_info_cxt(utf8_to_server_proc, finfo, |
334 | 0 | TopMemoryContext); |
335 | | /* Set Utf8ToServerConvProc only after data is fully valid */ |
336 | 0 | Utf8ToServerConvProc = finfo; |
337 | 0 | } |
338 | 0 | } |
339 | 0 | } |
340 | | |
341 | | /* |
342 | | * returns the current client encoding |
343 | | */ |
344 | | int |
345 | | pg_get_client_encoding(void) |
346 | 3.45k | { |
347 | 3.45k | return ClientEncoding->encoding; |
348 | 3.45k | } |
349 | | |
350 | | /* |
351 | | * returns the current client encoding name |
352 | | */ |
353 | | const char * |
354 | | pg_get_client_encoding_name(void) |
355 | 0 | { |
356 | 0 | return ClientEncoding->name; |
357 | 0 | } |
358 | | |
359 | | /* |
360 | | * Convert src string to another encoding (general case). |
361 | | * |
362 | | * See the notes about string conversion functions at the top of this file. |
363 | | */ |
364 | | unsigned char * |
365 | | pg_do_encoding_conversion(unsigned char *src, int len, |
366 | | int src_encoding, int dest_encoding) |
367 | 0 | { |
368 | 0 | unsigned char *result; |
369 | 0 | Oid proc; |
370 | |
|
371 | 0 | if (len <= 0) |
372 | 0 | return src; /* empty string is always valid */ |
373 | | |
374 | 0 | if (src_encoding == dest_encoding) |
375 | 0 | return src; /* no conversion required, assume valid */ |
376 | | |
377 | 0 | if (dest_encoding == PG_SQL_ASCII) |
378 | 0 | return src; /* any string is valid in SQL_ASCII */ |
379 | | |
380 | 0 | if (src_encoding == PG_SQL_ASCII) |
381 | 0 | { |
382 | | /* No conversion is possible, but we must validate the result */ |
383 | 0 | (void) pg_verify_mbstr(dest_encoding, (const char *) src, len, false); |
384 | 0 | return src; |
385 | 0 | } |
386 | | |
387 | 0 | if (!IsTransactionState()) /* shouldn't happen */ |
388 | 0 | elog(ERROR, "cannot perform encoding conversion outside a transaction"); |
389 | | |
390 | 0 | proc = FindDefaultConversionProc(src_encoding, dest_encoding); |
391 | 0 | if (!OidIsValid(proc)) |
392 | 0 | ereport(ERROR, |
393 | 0 | (errcode(ERRCODE_UNDEFINED_FUNCTION), |
394 | 0 | errmsg("default conversion function for encoding \"%s\" to \"%s\" does not exist", |
395 | 0 | pg_encoding_to_char(src_encoding), |
396 | 0 | pg_encoding_to_char(dest_encoding)))); |
397 | | |
398 | | /* |
399 | | * Allocate space for conversion result, being wary of integer overflow. |
400 | | * |
401 | | * len * MAX_CONVERSION_GROWTH is typically a vast overestimate of the |
402 | | * required space, so it might exceed MaxAllocSize even though the result |
403 | | * would actually fit. We do not want to hand back a result string that |
404 | | * exceeds MaxAllocSize, because callers might not cope gracefully --- but |
405 | | * if we just allocate more than that, and don't use it, that's fine. |
406 | | */ |
407 | 0 | if ((Size) len >= (MaxAllocHugeSize / (Size) MAX_CONVERSION_GROWTH)) |
408 | 0 | ereport(ERROR, |
409 | 0 | (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), |
410 | 0 | errmsg("out of memory"), |
411 | 0 | errdetail("String of %d bytes is too long for encoding conversion.", |
412 | 0 | len))); |
413 | | |
414 | 0 | result = (unsigned char *) |
415 | 0 | MemoryContextAllocHuge(CurrentMemoryContext, |
416 | 0 | (Size) len * MAX_CONVERSION_GROWTH + 1); |
417 | |
|
418 | 0 | (void) OidFunctionCall6(proc, |
419 | 0 | Int32GetDatum(src_encoding), |
420 | 0 | Int32GetDatum(dest_encoding), |
421 | 0 | CStringGetDatum((char *) src), |
422 | 0 | CStringGetDatum((char *) result), |
423 | 0 | Int32GetDatum(len), |
424 | 0 | BoolGetDatum(false)); |
425 | | |
426 | | /* |
427 | | * If the result is large, it's worth repalloc'ing to release any extra |
428 | | * space we asked for. The cutoff here is somewhat arbitrary, but we |
429 | | * *must* check when len * MAX_CONVERSION_GROWTH exceeds MaxAllocSize. |
430 | | */ |
431 | 0 | if (len > 1000000) |
432 | 0 | { |
433 | 0 | Size resultlen = strlen((char *) result); |
434 | |
|
435 | 0 | if (resultlen >= MaxAllocSize) |
436 | 0 | ereport(ERROR, |
437 | 0 | (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), |
438 | 0 | errmsg("out of memory"), |
439 | 0 | errdetail("String of %d bytes is too long for encoding conversion.", |
440 | 0 | len))); |
441 | | |
442 | 0 | result = (unsigned char *) repalloc(result, resultlen + 1); |
443 | 0 | } |
444 | | |
445 | 0 | return result; |
446 | 0 | } |
447 | | |
448 | | /* |
449 | | * Convert src string to another encoding. |
450 | | * |
451 | | * This function has a different API than the other conversion functions. |
452 | | * The caller should've looked up the conversion function using |
453 | | * FindDefaultConversionProc(). Unlike the other functions, the converted |
454 | | * result is not palloc'd. It is written to the caller-supplied buffer |
455 | | * instead. |
456 | | * |
457 | | * src_encoding - encoding to convert from |
458 | | * dest_encoding - encoding to convert to |
459 | | * src, srclen - input buffer and its length in bytes |
460 | | * dest, destlen - destination buffer and its size in bytes |
461 | | * |
462 | | * The output is null-terminated. |
463 | | * |
464 | | * If destlen < srclen * MAX_CONVERSION_INPUT_LENGTH + 1, the converted output |
465 | | * wouldn't necessarily fit in the output buffer, and the function will not |
466 | | * convert the whole input. |
467 | | * |
468 | | * TODO: The conversion function interface is not great. Firstly, it |
469 | | * would be nice to pass through the destination buffer size to the |
470 | | * conversion function, so that if you pass a shorter destination buffer, it |
471 | | * could still continue to fill up the whole buffer. Currently, we have to |
472 | | * assume worst case expansion and stop the conversion short, even if there |
473 | | * is in fact space left in the destination buffer. Secondly, it would be |
474 | | * nice to return the number of bytes written to the caller, to avoid a call |
475 | | * to strlen(). |
476 | | */ |
477 | | int |
478 | | pg_do_encoding_conversion_buf(Oid proc, |
479 | | int src_encoding, |
480 | | int dest_encoding, |
481 | | unsigned char *src, int srclen, |
482 | | unsigned char *dest, int destlen, |
483 | | bool noError) |
484 | 0 | { |
485 | 0 | Datum result; |
486 | | |
487 | | /* |
488 | | * If the destination buffer is not large enough to hold the result in the |
489 | | * worst case, limit the input size passed to the conversion function. |
490 | | */ |
491 | 0 | if ((Size) srclen >= ((destlen - 1) / (Size) MAX_CONVERSION_GROWTH)) |
492 | 0 | srclen = ((destlen - 1) / (Size) MAX_CONVERSION_GROWTH); |
493 | |
|
494 | 0 | result = OidFunctionCall6(proc, |
495 | 0 | Int32GetDatum(src_encoding), |
496 | 0 | Int32GetDatum(dest_encoding), |
497 | 0 | CStringGetDatum((char *) src), |
498 | 0 | CStringGetDatum((char *) dest), |
499 | 0 | Int32GetDatum(srclen), |
500 | 0 | BoolGetDatum(noError)); |
501 | 0 | return DatumGetInt32(result); |
502 | 0 | } |
503 | | |
504 | | /* |
505 | | * Convert string to encoding encoding_name. The source |
506 | | * encoding is the DB encoding. |
507 | | * |
508 | | * BYTEA convert_to(TEXT string, NAME encoding_name) |
509 | | */ |
510 | | Datum |
511 | | pg_convert_to(PG_FUNCTION_ARGS) |
512 | 0 | { |
513 | 0 | Datum string = PG_GETARG_DATUM(0); |
514 | 0 | Datum dest_encoding_name = PG_GETARG_DATUM(1); |
515 | 0 | Datum src_encoding_name = DirectFunctionCall1(namein, |
516 | 0 | CStringGetDatum(DatabaseEncoding->name)); |
517 | 0 | Datum result; |
518 | | |
519 | | /* |
520 | | * pg_convert expects a bytea as its first argument. We're passing it a |
521 | | * text argument here, relying on the fact that they are both in fact |
522 | | * varlena types, and thus structurally identical. |
523 | | */ |
524 | 0 | result = DirectFunctionCall3(pg_convert, string, |
525 | 0 | src_encoding_name, dest_encoding_name); |
526 | |
|
527 | 0 | PG_RETURN_DATUM(result); |
528 | 0 | } |
529 | | |
530 | | /* |
531 | | * Convert string from encoding encoding_name. The destination |
532 | | * encoding is the DB encoding. |
533 | | * |
534 | | * TEXT convert_from(BYTEA string, NAME encoding_name) |
535 | | */ |
536 | | Datum |
537 | | pg_convert_from(PG_FUNCTION_ARGS) |
538 | 0 | { |
539 | 0 | Datum string = PG_GETARG_DATUM(0); |
540 | 0 | Datum src_encoding_name = PG_GETARG_DATUM(1); |
541 | 0 | Datum dest_encoding_name = DirectFunctionCall1(namein, |
542 | 0 | CStringGetDatum(DatabaseEncoding->name)); |
543 | 0 | Datum result; |
544 | |
|
545 | 0 | result = DirectFunctionCall3(pg_convert, string, |
546 | 0 | src_encoding_name, dest_encoding_name); |
547 | | |
548 | | /* |
549 | | * pg_convert returns a bytea, which we in turn return as text, relying on |
550 | | * the fact that they are both in fact varlena types, and thus |
551 | | * structurally identical. Although not all bytea values are valid text, |
552 | | * in this case it will be because we've told pg_convert to return one |
553 | | * that is valid as text in the current database encoding. |
554 | | */ |
555 | 0 | PG_RETURN_DATUM(result); |
556 | 0 | } |
557 | | |
558 | | /* |
559 | | * Convert string between two arbitrary encodings. |
560 | | * |
561 | | * BYTEA convert(BYTEA string, NAME src_encoding_name, NAME dest_encoding_name) |
562 | | */ |
563 | | Datum |
564 | | pg_convert(PG_FUNCTION_ARGS) |
565 | 0 | { |
566 | 0 | bytea *string = PG_GETARG_BYTEA_PP(0); |
567 | 0 | char *src_encoding_name = NameStr(*PG_GETARG_NAME(1)); |
568 | 0 | int src_encoding = pg_char_to_encoding(src_encoding_name); |
569 | 0 | char *dest_encoding_name = NameStr(*PG_GETARG_NAME(2)); |
570 | 0 | int dest_encoding = pg_char_to_encoding(dest_encoding_name); |
571 | 0 | const char *src_str; |
572 | 0 | char *dest_str; |
573 | 0 | bytea *retval; |
574 | 0 | int len; |
575 | |
|
576 | 0 | if (src_encoding < 0) |
577 | 0 | ereport(ERROR, |
578 | 0 | (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
579 | 0 | errmsg("invalid source encoding name \"%s\"", |
580 | 0 | src_encoding_name))); |
581 | 0 | if (dest_encoding < 0) |
582 | 0 | ereport(ERROR, |
583 | 0 | (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
584 | 0 | errmsg("invalid destination encoding name \"%s\"", |
585 | 0 | dest_encoding_name))); |
586 | | |
587 | | /* make sure that source string is valid */ |
588 | 0 | len = VARSIZE_ANY_EXHDR(string); |
589 | 0 | src_str = VARDATA_ANY(string); |
590 | 0 | (void) pg_verify_mbstr(src_encoding, src_str, len, false); |
591 | | |
592 | | /* perform conversion */ |
593 | 0 | dest_str = (char *) pg_do_encoding_conversion((unsigned char *) unconstify(char *, src_str), |
594 | 0 | len, |
595 | 0 | src_encoding, |
596 | 0 | dest_encoding); |
597 | | |
598 | | |
599 | | /* return source string if no conversion happened */ |
600 | 0 | if (dest_str == src_str) |
601 | 0 | PG_RETURN_BYTEA_P(string); |
602 | | |
603 | | /* |
604 | | * build bytea data type structure. |
605 | | */ |
606 | 0 | len = strlen(dest_str); |
607 | 0 | retval = (bytea *) palloc(len + VARHDRSZ); |
608 | 0 | SET_VARSIZE(retval, len + VARHDRSZ); |
609 | 0 | memcpy(VARDATA(retval), dest_str, len); |
610 | 0 | pfree(dest_str); |
611 | | |
612 | | /* free memory if allocated by the toaster */ |
613 | 0 | PG_FREE_IF_COPY(string, 0); |
614 | |
|
615 | 0 | PG_RETURN_BYTEA_P(retval); |
616 | 0 | } |
617 | | |
618 | | /* |
619 | | * get the length of the string considered as text in the specified |
620 | | * encoding. Raises an error if the data is not valid in that |
621 | | * encoding. |
622 | | * |
623 | | * INT4 length (BYTEA string, NAME src_encoding_name) |
624 | | */ |
625 | | Datum |
626 | | length_in_encoding(PG_FUNCTION_ARGS) |
627 | 0 | { |
628 | 0 | bytea *string = PG_GETARG_BYTEA_PP(0); |
629 | 0 | char *src_encoding_name = NameStr(*PG_GETARG_NAME(1)); |
630 | 0 | int src_encoding = pg_char_to_encoding(src_encoding_name); |
631 | 0 | const char *src_str; |
632 | 0 | int len; |
633 | 0 | int retval; |
634 | |
|
635 | 0 | if (src_encoding < 0) |
636 | 0 | ereport(ERROR, |
637 | 0 | (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
638 | 0 | errmsg("invalid encoding name \"%s\"", |
639 | 0 | src_encoding_name))); |
640 | | |
641 | 0 | len = VARSIZE_ANY_EXHDR(string); |
642 | 0 | src_str = VARDATA_ANY(string); |
643 | |
|
644 | 0 | retval = pg_verify_mbstr_len(src_encoding, src_str, len, false); |
645 | |
|
646 | 0 | PG_RETURN_INT32(retval); |
647 | 0 | } |
648 | | |
649 | | /* |
650 | | * Get maximum multibyte character length in the specified encoding. |
651 | | * |
652 | | * Note encoding is specified numerically, not by name as above. |
653 | | */ |
654 | | Datum |
655 | | pg_encoding_max_length_sql(PG_FUNCTION_ARGS) |
656 | 0 | { |
657 | 0 | int encoding = PG_GETARG_INT32(0); |
658 | |
|
659 | 0 | if (PG_VALID_ENCODING(encoding)) |
660 | 0 | PG_RETURN_INT32(pg_wchar_table[encoding].maxmblen); |
661 | 0 | else |
662 | 0 | PG_RETURN_NULL(); |
663 | 0 | } |
664 | | |
665 | | /* |
666 | | * Convert client encoding to server encoding. |
667 | | * |
668 | | * See the notes about string conversion functions at the top of this file. |
669 | | */ |
670 | | char * |
671 | | pg_client_to_server(const char *s, int len) |
672 | 0 | { |
673 | 0 | return pg_any_to_server(s, len, ClientEncoding->encoding); |
674 | 0 | } |
675 | | |
676 | | /* |
677 | | * Convert any encoding to server encoding. |
678 | | * |
679 | | * See the notes about string conversion functions at the top of this file. |
680 | | * |
681 | | * Unlike the other string conversion functions, this will apply validation |
682 | | * even if encoding == DatabaseEncoding->encoding. This is because this is |
683 | | * used to process data coming in from outside the database, and we never |
684 | | * want to just assume validity. |
685 | | */ |
686 | | char * |
687 | | pg_any_to_server(const char *s, int len, int encoding) |
688 | 0 | { |
689 | 0 | if (len <= 0) |
690 | 0 | return unconstify(char *, s); /* empty string is always valid */ |
691 | | |
692 | 0 | if (encoding == DatabaseEncoding->encoding || |
693 | 0 | encoding == PG_SQL_ASCII) |
694 | 0 | { |
695 | | /* |
696 | | * No conversion is needed, but we must still validate the data. |
697 | | */ |
698 | 0 | (void) pg_verify_mbstr(DatabaseEncoding->encoding, s, len, false); |
699 | 0 | return unconstify(char *, s); |
700 | 0 | } |
701 | | |
702 | 0 | if (DatabaseEncoding->encoding == PG_SQL_ASCII) |
703 | 0 | { |
704 | | /* |
705 | | * No conversion is possible, but we must still validate the data, |
706 | | * because the client-side code might have done string escaping using |
707 | | * the selected client_encoding. If the client encoding is ASCII-safe |
708 | | * then we just do a straight validation under that encoding. For an |
709 | | * ASCII-unsafe encoding we have a problem: we dare not pass such data |
710 | | * to the parser but we have no way to convert it. We compromise by |
711 | | * rejecting the data if it contains any non-ASCII characters. |
712 | | */ |
713 | 0 | if (PG_VALID_BE_ENCODING(encoding)) |
714 | 0 | (void) pg_verify_mbstr(encoding, s, len, false); |
715 | 0 | else |
716 | 0 | { |
717 | 0 | int i; |
718 | |
|
719 | 0 | for (i = 0; i < len; i++) |
720 | 0 | { |
721 | 0 | if (s[i] == '\0' || IS_HIGHBIT_SET(s[i])) |
722 | 0 | ereport(ERROR, |
723 | 0 | (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE), |
724 | 0 | errmsg("invalid byte value for encoding \"%s\": 0x%02x", |
725 | 0 | pg_enc2name_tbl[PG_SQL_ASCII].name, |
726 | 0 | (unsigned char) s[i]))); |
727 | 0 | } |
728 | 0 | } |
729 | 0 | return unconstify(char *, s); |
730 | 0 | } |
731 | | |
732 | | /* Fast path if we can use cached conversion function */ |
733 | 0 | if (encoding == ClientEncoding->encoding) |
734 | 0 | return perform_default_encoding_conversion(s, len, true); |
735 | | |
736 | | /* General case ... will not work outside transactions */ |
737 | 0 | return (char *) pg_do_encoding_conversion((unsigned char *) unconstify(char *, s), |
738 | 0 | len, |
739 | 0 | encoding, |
740 | 0 | DatabaseEncoding->encoding); |
741 | 0 | } |
742 | | |
743 | | /* |
744 | | * Convert server encoding to client encoding. |
745 | | * |
746 | | * See the notes about string conversion functions at the top of this file. |
747 | | */ |
748 | | char * |
749 | | pg_server_to_client(const char *s, int len) |
750 | 0 | { |
751 | 0 | return pg_server_to_any(s, len, ClientEncoding->encoding); |
752 | 0 | } |
753 | | |
754 | | /* |
755 | | * Convert server encoding to any encoding. |
756 | | * |
757 | | * See the notes about string conversion functions at the top of this file. |
758 | | */ |
759 | | char * |
760 | | pg_server_to_any(const char *s, int len, int encoding) |
761 | 0 | { |
762 | 0 | if (len <= 0) |
763 | 0 | return unconstify(char *, s); /* empty string is always valid */ |
764 | | |
765 | 0 | if (encoding == DatabaseEncoding->encoding || |
766 | 0 | encoding == PG_SQL_ASCII) |
767 | 0 | return unconstify(char *, s); /* assume data is valid */ |
768 | | |
769 | 0 | if (DatabaseEncoding->encoding == PG_SQL_ASCII) |
770 | 0 | { |
771 | | /* No conversion is possible, but we must validate the result */ |
772 | 0 | (void) pg_verify_mbstr(encoding, s, len, false); |
773 | 0 | return unconstify(char *, s); |
774 | 0 | } |
775 | | |
776 | | /* Fast path if we can use cached conversion function */ |
777 | 0 | if (encoding == ClientEncoding->encoding) |
778 | 0 | return perform_default_encoding_conversion(s, len, false); |
779 | | |
780 | | /* General case ... will not work outside transactions */ |
781 | 0 | return (char *) pg_do_encoding_conversion((unsigned char *) unconstify(char *, s), |
782 | 0 | len, |
783 | 0 | DatabaseEncoding->encoding, |
784 | 0 | encoding); |
785 | 0 | } |
786 | | |
787 | | /* |
788 | | * Perform default encoding conversion using cached FmgrInfo. Since |
789 | | * this function does not access database at all, it is safe to call |
790 | | * outside transactions. If the conversion has not been set up by |
791 | | * SetClientEncoding(), no conversion is performed. |
792 | | */ |
793 | | static char * |
794 | | perform_default_encoding_conversion(const char *src, int len, |
795 | | bool is_client_to_server) |
796 | 0 | { |
797 | 0 | char *result; |
798 | 0 | int src_encoding, |
799 | 0 | dest_encoding; |
800 | 0 | FmgrInfo *flinfo; |
801 | |
|
802 | 0 | if (is_client_to_server) |
803 | 0 | { |
804 | 0 | src_encoding = ClientEncoding->encoding; |
805 | 0 | dest_encoding = DatabaseEncoding->encoding; |
806 | 0 | flinfo = ToServerConvProc; |
807 | 0 | } |
808 | 0 | else |
809 | 0 | { |
810 | 0 | src_encoding = DatabaseEncoding->encoding; |
811 | 0 | dest_encoding = ClientEncoding->encoding; |
812 | 0 | flinfo = ToClientConvProc; |
813 | 0 | } |
814 | |
|
815 | 0 | if (flinfo == NULL) |
816 | 0 | return unconstify(char *, src); |
817 | | |
818 | | /* |
819 | | * Allocate space for conversion result, being wary of integer overflow. |
820 | | * See comments in pg_do_encoding_conversion. |
821 | | */ |
822 | 0 | if ((Size) len >= (MaxAllocHugeSize / (Size) MAX_CONVERSION_GROWTH)) |
823 | 0 | ereport(ERROR, |
824 | 0 | (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), |
825 | 0 | errmsg("out of memory"), |
826 | 0 | errdetail("String of %d bytes is too long for encoding conversion.", |
827 | 0 | len))); |
828 | | |
829 | 0 | result = (char *) |
830 | 0 | MemoryContextAllocHuge(CurrentMemoryContext, |
831 | 0 | (Size) len * MAX_CONVERSION_GROWTH + 1); |
832 | |
|
833 | 0 | FunctionCall6(flinfo, |
834 | 0 | Int32GetDatum(src_encoding), |
835 | 0 | Int32GetDatum(dest_encoding), |
836 | 0 | CStringGetDatum(src), |
837 | 0 | CStringGetDatum(result), |
838 | 0 | Int32GetDatum(len), |
839 | 0 | BoolGetDatum(false)); |
840 | | |
841 | | /* |
842 | | * Release extra space if there might be a lot --- see comments in |
843 | | * pg_do_encoding_conversion. |
844 | | */ |
845 | 0 | if (len > 1000000) |
846 | 0 | { |
847 | 0 | Size resultlen = strlen(result); |
848 | |
|
849 | 0 | if (resultlen >= MaxAllocSize) |
850 | 0 | ereport(ERROR, |
851 | 0 | (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), |
852 | 0 | errmsg("out of memory"), |
853 | 0 | errdetail("String of %d bytes is too long for encoding conversion.", |
854 | 0 | len))); |
855 | | |
856 | 0 | result = (char *) repalloc(result, resultlen + 1); |
857 | 0 | } |
858 | | |
859 | 0 | return result; |
860 | 0 | } |
861 | | |
862 | | /* |
863 | | * Convert a single Unicode code point into a string in the server encoding. |
864 | | * |
865 | | * The code point given by "c" is converted and stored at *s, which must |
866 | | * have at least MAX_UNICODE_EQUIVALENT_STRING+1 bytes available. |
867 | | * The output will have a trailing '\0'. Throws error if the conversion |
868 | | * cannot be performed. |
869 | | * |
870 | | * Note that this relies on having previously looked up any required |
871 | | * conversion function. That's partly for speed but mostly because the parser |
872 | | * may call this outside any transaction, or in an aborted transaction. |
873 | | */ |
874 | | void |
875 | | pg_unicode_to_server(char32_t c, unsigned char *s) |
876 | 2.80k | { |
877 | 2.80k | unsigned char c_as_utf8[MAX_MULTIBYTE_CHAR_LEN + 1]; |
878 | 2.80k | int c_as_utf8_len; |
879 | 2.80k | int server_encoding; |
880 | | |
881 | | /* |
882 | | * Complain if invalid Unicode code point. The choice of errcode here is |
883 | | * debatable, but really our caller should have checked this anyway. |
884 | | */ |
885 | 2.80k | if (!is_valid_unicode_codepoint(c)) |
886 | 2.80k | ereport(ERROR, |
887 | 2.80k | (errcode(ERRCODE_SYNTAX_ERROR), |
888 | 2.80k | errmsg("invalid Unicode code point"))); |
889 | | |
890 | | /* Otherwise, if it's in ASCII range, conversion is trivial */ |
891 | 2.80k | if (c <= 0x7F) |
892 | 2.58k | { |
893 | 2.58k | s[0] = (unsigned char) c; |
894 | 2.58k | s[1] = '\0'; |
895 | 2.58k | return; |
896 | 2.58k | } |
897 | | |
898 | | /* If the server encoding is UTF-8, we just need to reformat the code */ |
899 | 216 | server_encoding = GetDatabaseEncoding(); |
900 | 216 | if (server_encoding == PG_UTF8) |
901 | 0 | { |
902 | 0 | unicode_to_utf8(c, s); |
903 | 0 | s[pg_utf_mblen(s)] = '\0'; |
904 | 0 | return; |
905 | 0 | } |
906 | | |
907 | | /* For all other cases, we must have a conversion function available */ |
908 | 216 | if (Utf8ToServerConvProc == NULL) |
909 | 216 | ereport(ERROR, |
910 | 216 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
911 | 216 | errmsg("conversion between %s and %s is not supported", |
912 | 216 | pg_enc2name_tbl[PG_UTF8].name, |
913 | 216 | GetDatabaseEncodingName()))); |
914 | | |
915 | | /* Construct UTF-8 source string */ |
916 | 216 | unicode_to_utf8(c, c_as_utf8); |
917 | 216 | c_as_utf8_len = pg_utf_mblen(c_as_utf8); |
918 | 216 | c_as_utf8[c_as_utf8_len] = '\0'; |
919 | | |
920 | | /* Convert, or throw error if we can't */ |
921 | 216 | FunctionCall6(Utf8ToServerConvProc, |
922 | 216 | Int32GetDatum(PG_UTF8), |
923 | 216 | Int32GetDatum(server_encoding), |
924 | 216 | CStringGetDatum((char *) c_as_utf8), |
925 | 216 | CStringGetDatum((char *) s), |
926 | 216 | Int32GetDatum(c_as_utf8_len), |
927 | 216 | BoolGetDatum(false)); |
928 | 216 | } |
929 | | |
930 | | /* |
931 | | * Convert a single Unicode code point into a string in the server encoding. |
932 | | * |
933 | | * Same as pg_unicode_to_server(), except that we don't throw errors, |
934 | | * but simply return false on conversion failure. |
935 | | */ |
936 | | bool |
937 | | pg_unicode_to_server_noerror(char32_t c, unsigned char *s) |
938 | 16.4k | { |
939 | 16.4k | unsigned char c_as_utf8[MAX_MULTIBYTE_CHAR_LEN + 1]; |
940 | 16.4k | int c_as_utf8_len; |
941 | 16.4k | int converted_len; |
942 | 16.4k | int server_encoding; |
943 | | |
944 | | /* Fail if invalid Unicode code point */ |
945 | 16.4k | if (!is_valid_unicode_codepoint(c)) |
946 | 0 | return false; |
947 | | |
948 | | /* Otherwise, if it's in ASCII range, conversion is trivial */ |
949 | 16.4k | if (c <= 0x7F) |
950 | 16.3k | { |
951 | 16.3k | s[0] = (unsigned char) c; |
952 | 16.3k | s[1] = '\0'; |
953 | 16.3k | return true; |
954 | 16.3k | } |
955 | | |
956 | | /* If the server encoding is UTF-8, we just need to reformat the code */ |
957 | 107 | server_encoding = GetDatabaseEncoding(); |
958 | 107 | if (server_encoding == PG_UTF8) |
959 | 0 | { |
960 | 0 | unicode_to_utf8(c, s); |
961 | 0 | s[pg_utf_mblen(s)] = '\0'; |
962 | 0 | return true; |
963 | 0 | } |
964 | | |
965 | | /* For all other cases, we must have a conversion function available */ |
966 | 107 | if (Utf8ToServerConvProc == NULL) |
967 | 107 | return false; |
968 | | |
969 | | /* Construct UTF-8 source string */ |
970 | 0 | unicode_to_utf8(c, c_as_utf8); |
971 | 0 | c_as_utf8_len = pg_utf_mblen(c_as_utf8); |
972 | 0 | c_as_utf8[c_as_utf8_len] = '\0'; |
973 | | |
974 | | /* Convert, but without throwing error if we can't */ |
975 | 0 | converted_len = DatumGetInt32(FunctionCall6(Utf8ToServerConvProc, |
976 | 0 | Int32GetDatum(PG_UTF8), |
977 | 0 | Int32GetDatum(server_encoding), |
978 | 0 | CStringGetDatum((char *) c_as_utf8), |
979 | 0 | CStringGetDatum((char *) s), |
980 | 0 | Int32GetDatum(c_as_utf8_len), |
981 | 0 | BoolGetDatum(true))); |
982 | | |
983 | | /* Conversion was successful iff it consumed the whole input */ |
984 | 0 | return (converted_len == c_as_utf8_len); |
985 | 107 | } |
986 | | |
987 | | |
988 | | /* convert a multibyte string to a wchar */ |
989 | | int |
990 | | pg_mb2wchar(const char *from, pg_wchar *to) |
991 | 0 | { |
992 | 0 | return pg_wchar_table[DatabaseEncoding->encoding].mb2wchar_with_len((const unsigned char *) from, to, strlen(from)); |
993 | 0 | } |
994 | | |
995 | | /* convert a multibyte string to a wchar with a limited length */ |
996 | | int |
997 | | pg_mb2wchar_with_len(const char *from, pg_wchar *to, int len) |
998 | 0 | { |
999 | 0 | return pg_wchar_table[DatabaseEncoding->encoding].mb2wchar_with_len((const unsigned char *) from, to, len); |
1000 | 0 | } |
1001 | | |
1002 | | /* same, with any encoding */ |
1003 | | int |
1004 | | pg_encoding_mb2wchar_with_len(int encoding, |
1005 | | const char *from, pg_wchar *to, int len) |
1006 | 0 | { |
1007 | 0 | return pg_wchar_table[encoding].mb2wchar_with_len((const unsigned char *) from, to, len); |
1008 | 0 | } |
1009 | | |
1010 | | /* convert a wchar string to a multibyte */ |
1011 | | int |
1012 | | pg_wchar2mb(const pg_wchar *from, char *to) |
1013 | 0 | { |
1014 | 0 | return pg_wchar_table[DatabaseEncoding->encoding].wchar2mb_with_len(from, (unsigned char *) to, pg_wchar_strlen(from)); |
1015 | 0 | } |
1016 | | |
1017 | | /* convert a wchar string to a multibyte with a limited length */ |
1018 | | int |
1019 | | pg_wchar2mb_with_len(const pg_wchar *from, char *to, int len) |
1020 | 0 | { |
1021 | 0 | return pg_wchar_table[DatabaseEncoding->encoding].wchar2mb_with_len(from, (unsigned char *) to, len); |
1022 | 0 | } |
1023 | | |
1024 | | /* same, with any encoding */ |
1025 | | int |
1026 | | pg_encoding_wchar2mb_with_len(int encoding, |
1027 | | const pg_wchar *from, char *to, int len) |
1028 | 0 | { |
1029 | 0 | return pg_wchar_table[encoding].wchar2mb_with_len(from, (unsigned char *) to, len); |
1030 | 0 | } |
1031 | | |
1032 | | /* |
1033 | | * Returns the byte length of a multibyte character sequence in a |
1034 | | * null-terminated string. Raises an illegal byte sequence error if the |
1035 | | * sequence would hit a null terminator. |
1036 | | * |
1037 | | * The caller is expected to have checked for a terminator at *mbstr == 0 |
1038 | | * before calling, but some callers want 1 in that case, so this function |
1039 | | * continues that tradition. |
1040 | | * |
1041 | | * This must only be used for strings that have a null-terminator to enable |
1042 | | * bounds detection. |
1043 | | */ |
1044 | | int |
1045 | | pg_mblen_cstr(const char *mbstr) |
1046 | 0 | { |
1047 | 0 | int length = pg_wchar_table[DatabaseEncoding->encoding].mblen((const unsigned char *) mbstr); |
1048 | | |
1049 | | /* |
1050 | | * The .mblen functions return 1 when given a pointer to a terminator. |
1051 | | * Some callers depend on that, so we tolerate it for now. Well-behaved |
1052 | | * callers check the leading byte for a terminator *before* calling. |
1053 | | */ |
1054 | 0 | for (int i = 1; i < length; ++i) |
1055 | 0 | if (unlikely(mbstr[i] == 0)) |
1056 | 0 | report_invalid_encoding_db(mbstr, length, i); |
1057 | | |
1058 | | /* |
1059 | | * String should be NUL-terminated, but checking that would make typical |
1060 | | * callers O(N^2), tripling Valgrind check-world time. Unless |
1061 | | * VALGRIND_EXPENSIVE, check 1 byte after each actual character. (If we |
1062 | | * found a character, not a terminator, the next byte must be a terminator |
1063 | | * or the start of the next character.) If the caller iterates the whole |
1064 | | * string, the last call will diagnose a missing terminator. |
1065 | | */ |
1066 | 0 | if (mbstr[0] != '\0') |
1067 | 0 | { |
1068 | | #ifdef VALGRIND_EXPENSIVE |
1069 | | VALGRIND_CHECK_MEM_IS_DEFINED(mbstr, strlen(mbstr)); |
1070 | | #else |
1071 | 0 | VALGRIND_CHECK_MEM_IS_DEFINED(mbstr + length, 1); |
1072 | 0 | #endif |
1073 | 0 | } |
1074 | |
|
1075 | 0 | return length; |
1076 | 0 | } |
1077 | | |
1078 | | /* |
1079 | | * Returns the byte length of a multibyte character sequence bounded by a range |
1080 | | * [mbstr, end) of at least one byte in size. Raises an illegal byte sequence |
1081 | | * error if the sequence would exceed the range. |
1082 | | */ |
1083 | | int |
1084 | | pg_mblen_range(const char *mbstr, const char *end) |
1085 | 0 | { |
1086 | 0 | int length = pg_wchar_table[DatabaseEncoding->encoding].mblen((const unsigned char *) mbstr); |
1087 | |
|
1088 | 0 | Assert(end > mbstr); |
1089 | |
|
1090 | 0 | if (unlikely(mbstr + length > end)) |
1091 | 0 | report_invalid_encoding_db(mbstr, length, end - mbstr); |
1092 | |
|
1093 | | #ifdef VALGRIND_EXPENSIVE |
1094 | | VALGRIND_CHECK_MEM_IS_DEFINED(mbstr, end - mbstr); |
1095 | | #else |
1096 | 0 | VALGRIND_CHECK_MEM_IS_DEFINED(mbstr, length); |
1097 | 0 | #endif |
1098 | |
|
1099 | 0 | return length; |
1100 | 0 | } |
1101 | | |
1102 | | /* |
1103 | | * Returns the byte length of a multibyte character sequence bounded by a range |
1104 | | * extending for 'limit' bytes, which must be at least one. Raises an illegal |
1105 | | * byte sequence error if the sequence would exceed the range. |
1106 | | */ |
1107 | | int |
1108 | | pg_mblen_with_len(const char *mbstr, int limit) |
1109 | 0 | { |
1110 | 0 | int length = pg_wchar_table[DatabaseEncoding->encoding].mblen((const unsigned char *) mbstr); |
1111 | |
|
1112 | 0 | Assert(limit >= 1); |
1113 | |
|
1114 | 0 | if (unlikely(length > limit)) |
1115 | 0 | report_invalid_encoding_db(mbstr, length, limit); |
1116 | |
|
1117 | | #ifdef VALGRIND_EXPENSIVE |
1118 | | VALGRIND_CHECK_MEM_IS_DEFINED(mbstr, limit); |
1119 | | #else |
1120 | 0 | VALGRIND_CHECK_MEM_IS_DEFINED(mbstr, length); |
1121 | 0 | #endif |
1122 | |
|
1123 | 0 | return length; |
1124 | 0 | } |
1125 | | |
1126 | | |
1127 | | /* |
1128 | | * Returns the length of a multibyte character sequence, without any |
1129 | | * validation of bounds. |
1130 | | * |
1131 | | * PLEASE NOTE: This function can only be used safely if the caller has |
1132 | | * already verified the input string, since otherwise there is a risk of |
1133 | | * overrunning the buffer if the string is invalid. A prior call to a |
1134 | | * pg_mbstrlen* function suffices. |
1135 | | */ |
1136 | | int |
1137 | | pg_mblen_unbounded(const char *mbstr) |
1138 | 0 | { |
1139 | 0 | int length = pg_wchar_table[DatabaseEncoding->encoding].mblen((const unsigned char *) mbstr); |
1140 | |
|
1141 | 0 | VALGRIND_CHECK_MEM_IS_DEFINED(mbstr, length); |
1142 | |
|
1143 | 0 | return length; |
1144 | 0 | } |
1145 | | |
1146 | | /* |
1147 | | * Historical name for pg_mblen_unbounded(). Should not be used and will be |
1148 | | * removed in a later version. |
1149 | | */ |
1150 | | int |
1151 | | pg_mblen(const char *mbstr) |
1152 | 0 | { |
1153 | 0 | return pg_mblen_unbounded(mbstr); |
1154 | 0 | } |
1155 | | |
1156 | | /* returns the display length of a multibyte character */ |
1157 | | int |
1158 | | pg_dsplen(const char *mbstr) |
1159 | 0 | { |
1160 | 0 | return pg_wchar_table[DatabaseEncoding->encoding].dsplen((const unsigned char *) mbstr); |
1161 | 0 | } |
1162 | | |
1163 | | /* returns the length (counted in wchars) of a multibyte string */ |
1164 | | int |
1165 | | pg_mbstrlen(const char *mbstr) |
1166 | 0 | { |
1167 | 0 | int len = 0; |
1168 | | |
1169 | | /* optimization for single byte encoding */ |
1170 | 0 | if (pg_database_encoding_max_length() == 1) |
1171 | 0 | return strlen(mbstr); |
1172 | | |
1173 | 0 | while (*mbstr) |
1174 | 0 | { |
1175 | 0 | mbstr += pg_mblen_cstr(mbstr); |
1176 | 0 | len++; |
1177 | 0 | } |
1178 | 0 | return len; |
1179 | 0 | } |
1180 | | |
1181 | | /* |
1182 | | * returns the length (counted in wchars) of a multibyte string |
1183 | | * (stops at the first of "limit" or a NUL) |
1184 | | */ |
1185 | | int |
1186 | | pg_mbstrlen_with_len(const char *mbstr, int limit) |
1187 | 4.48k | { |
1188 | 4.48k | int len = 0; |
1189 | | |
1190 | | /* optimization for single byte encoding */ |
1191 | 4.48k | if (pg_database_encoding_max_length() == 1) |
1192 | 4.48k | return limit; |
1193 | | |
1194 | 0 | while (limit > 0 && *mbstr) |
1195 | 0 | { |
1196 | 0 | int l = pg_mblen_with_len(mbstr, limit); |
1197 | |
|
1198 | 0 | limit -= l; |
1199 | 0 | mbstr += l; |
1200 | 0 | len++; |
1201 | 0 | } |
1202 | 0 | return len; |
1203 | 4.48k | } |
1204 | | |
1205 | | /* |
1206 | | * returns the byte length of a multibyte string |
1207 | | * (not necessarily NULL terminated) |
1208 | | * that is no longer than limit. |
1209 | | * this function does not break multibyte character boundary. |
1210 | | */ |
1211 | | int |
1212 | | pg_mbcliplen(const char *mbstr, int len, int limit) |
1213 | 1.81k | { |
1214 | 1.81k | return pg_encoding_mbcliplen(DatabaseEncoding->encoding, mbstr, |
1215 | 1.81k | len, limit); |
1216 | 1.81k | } |
1217 | | |
1218 | | /* |
1219 | | * pg_mbcliplen with specified encoding; string must be valid in encoding |
1220 | | */ |
1221 | | int |
1222 | | pg_encoding_mbcliplen(int encoding, const char *mbstr, |
1223 | | int len, int limit) |
1224 | 1.81k | { |
1225 | 1.81k | mblen_function mblen_fn; |
1226 | 1.81k | int clen = 0; |
1227 | 1.81k | int l; |
1228 | | |
1229 | | /* optimization for single byte encoding */ |
1230 | 1.81k | if (pg_encoding_max_length(encoding) == 1) |
1231 | 1.81k | return cliplen(mbstr, len, limit); |
1232 | | |
1233 | 0 | mblen_fn = pg_wchar_table[encoding].mblen; |
1234 | |
|
1235 | 0 | while (len > 0 && *mbstr) |
1236 | 0 | { |
1237 | 0 | l = (*mblen_fn) ((const unsigned char *) mbstr); |
1238 | 0 | if ((clen + l) > limit) |
1239 | 0 | break; |
1240 | 0 | clen += l; |
1241 | 0 | if (clen == limit) |
1242 | 0 | break; |
1243 | 0 | len -= l; |
1244 | 0 | mbstr += l; |
1245 | 0 | } |
1246 | 0 | return clen; |
1247 | 1.81k | } |
1248 | | |
1249 | | /* |
1250 | | * Similar to pg_mbcliplen except the limit parameter specifies the |
1251 | | * character length, not the byte length. |
1252 | | */ |
1253 | | int |
1254 | | pg_mbcharcliplen(const char *mbstr, int len, int limit) |
1255 | 0 | { |
1256 | 0 | int clen = 0; |
1257 | 0 | int nch = 0; |
1258 | 0 | int l; |
1259 | | |
1260 | | /* optimization for single byte encoding */ |
1261 | 0 | if (pg_database_encoding_max_length() == 1) |
1262 | 0 | return cliplen(mbstr, len, limit); |
1263 | | |
1264 | 0 | while (len > 0 && *mbstr) |
1265 | 0 | { |
1266 | 0 | l = pg_mblen_with_len(mbstr, len); |
1267 | 0 | nch++; |
1268 | 0 | if (nch > limit) |
1269 | 0 | break; |
1270 | 0 | clen += l; |
1271 | 0 | len -= l; |
1272 | 0 | mbstr += l; |
1273 | 0 | } |
1274 | 0 | return clen; |
1275 | 0 | } |
1276 | | |
1277 | | /* mbcliplen for any single-byte encoding */ |
1278 | | static int |
1279 | | cliplen(const char *str, int len, int limit) |
1280 | 1.81k | { |
1281 | 1.81k | int l = 0; |
1282 | | |
1283 | 1.81k | len = Min(len, limit); |
1284 | 116k | while (l < len && str[l]) |
1285 | 114k | l++; |
1286 | 1.81k | return l; |
1287 | 1.81k | } |
1288 | | |
1289 | | void |
1290 | | SetDatabaseEncoding(int encoding) |
1291 | 0 | { |
1292 | 0 | if (!PG_VALID_BE_ENCODING(encoding)) |
1293 | 0 | elog(ERROR, "invalid database encoding: %d", encoding); |
1294 | | |
1295 | 0 | DatabaseEncoding = &pg_enc2name_tbl[encoding]; |
1296 | 0 | Assert(DatabaseEncoding->encoding == encoding); |
1297 | 0 | } |
1298 | | |
1299 | | void |
1300 | | SetMessageEncoding(int encoding) |
1301 | 0 | { |
1302 | | /* Some calls happen before we can elog()! */ |
1303 | 0 | Assert(PG_VALID_ENCODING(encoding)); |
1304 | |
|
1305 | 0 | MessageEncoding = &pg_enc2name_tbl[encoding]; |
1306 | 0 | Assert(MessageEncoding->encoding == encoding); |
1307 | 0 | } |
1308 | | |
1309 | | #ifdef ENABLE_NLS |
1310 | | /* |
1311 | | * Make one bind_textdomain_codeset() call, translating a pg_enc to a gettext |
1312 | | * codeset. Can fail for gettext-internal causes like out-of-memory. |
1313 | | */ |
1314 | | static bool |
1315 | | raw_pg_bind_textdomain_codeset(const char *domainname, int encoding) |
1316 | | { |
1317 | | bool elog_ok = (CurrentMemoryContext != NULL); |
1318 | | |
1319 | | if (!PG_VALID_ENCODING(encoding) || pg_enc2gettext_tbl[encoding] == NULL) |
1320 | | return false; |
1321 | | |
1322 | | if (bind_textdomain_codeset(domainname, |
1323 | | pg_enc2gettext_tbl[encoding]) != NULL) |
1324 | | return true; |
1325 | | |
1326 | | if (elog_ok) |
1327 | | elog(LOG, "bind_textdomain_codeset failed"); |
1328 | | else |
1329 | | write_stderr("bind_textdomain_codeset failed"); |
1330 | | |
1331 | | return false; |
1332 | | } |
1333 | | |
1334 | | /* |
1335 | | * Bind a gettext message domain to the codeset corresponding to the database |
1336 | | * encoding. For SQL_ASCII, instead bind to the codeset implied by LC_CTYPE. |
1337 | | * Return the MessageEncoding implied by the new settings. |
1338 | | * |
1339 | | * On most platforms, gettext defaults to the codeset implied by LC_CTYPE. |
1340 | | * When that matches the database encoding, we don't need to do anything. In |
1341 | | * CREATE DATABASE, we enforce or trust that the locale's codeset matches the |
1342 | | * database encoding, except for the C locale. (On Windows, we also permit a |
1343 | | * discrepancy under the UTF8 encoding.) For the C locale, explicitly bind |
1344 | | * gettext to the right codeset. |
1345 | | * |
1346 | | * On Windows, gettext defaults to the Windows ANSI code page. This is a |
1347 | | * convenient departure for software that passes the strings to Windows ANSI |
1348 | | * APIs, but we don't do that. Compel gettext to use database encoding or, |
1349 | | * failing that, the LC_CTYPE encoding as it would on other platforms. |
1350 | | * |
1351 | | * This function is called before elog() and palloc() are usable. |
1352 | | */ |
1353 | | int |
1354 | | pg_bind_textdomain_codeset(const char *domainname) |
1355 | | { |
1356 | | bool elog_ok = (CurrentMemoryContext != NULL); |
1357 | | int encoding = GetDatabaseEncoding(); |
1358 | | int new_msgenc; |
1359 | | |
1360 | | #ifndef WIN32 |
1361 | | const char *ctype = setlocale(LC_CTYPE, NULL); |
1362 | | |
1363 | | if (pg_strcasecmp(ctype, "C") == 0 || pg_strcasecmp(ctype, "POSIX") == 0) |
1364 | | #endif |
1365 | | if (encoding != PG_SQL_ASCII && |
1366 | | raw_pg_bind_textdomain_codeset(domainname, encoding)) |
1367 | | return encoding; |
1368 | | |
1369 | | new_msgenc = pg_get_encoding_from_locale(NULL, elog_ok); |
1370 | | if (new_msgenc < 0) |
1371 | | new_msgenc = PG_SQL_ASCII; |
1372 | | |
1373 | | #ifdef WIN32 |
1374 | | if (!raw_pg_bind_textdomain_codeset(domainname, new_msgenc)) |
1375 | | /* On failure, the old message encoding remains valid. */ |
1376 | | return GetMessageEncoding(); |
1377 | | #endif |
1378 | | |
1379 | | return new_msgenc; |
1380 | | } |
1381 | | #endif |
1382 | | |
1383 | | /* |
1384 | | * The database encoding, also called the server encoding, represents the |
1385 | | * encoding of data stored in text-like data types. Affected types include |
1386 | | * cstring, text, varchar, name, xml, and json. |
1387 | | */ |
1388 | | int |
1389 | | GetDatabaseEncoding(void) |
1390 | 3.86M | { |
1391 | 3.86M | return DatabaseEncoding->encoding; |
1392 | 3.86M | } |
1393 | | |
1394 | | const char * |
1395 | | GetDatabaseEncodingName(void) |
1396 | 216 | { |
1397 | 216 | return DatabaseEncoding->name; |
1398 | 216 | } |
1399 | | |
1400 | | Datum |
1401 | | getdatabaseencoding(PG_FUNCTION_ARGS) |
1402 | 0 | { |
1403 | 0 | return DirectFunctionCall1(namein, CStringGetDatum(DatabaseEncoding->name)); |
1404 | 0 | } |
1405 | | |
1406 | | Datum |
1407 | | pg_client_encoding(PG_FUNCTION_ARGS) |
1408 | 0 | { |
1409 | 0 | return DirectFunctionCall1(namein, CStringGetDatum(ClientEncoding->name)); |
1410 | 0 | } |
1411 | | |
1412 | | Datum |
1413 | | PG_char_to_encoding(PG_FUNCTION_ARGS) |
1414 | 0 | { |
1415 | 0 | Name s = PG_GETARG_NAME(0); |
1416 | |
|
1417 | 0 | PG_RETURN_INT32(pg_char_to_encoding(NameStr(*s))); |
1418 | 0 | } |
1419 | | |
1420 | | Datum |
1421 | | PG_encoding_to_char(PG_FUNCTION_ARGS) |
1422 | 0 | { |
1423 | 0 | int32 encoding = PG_GETARG_INT32(0); |
1424 | 0 | const char *encoding_name = pg_encoding_to_char(encoding); |
1425 | |
|
1426 | 0 | return DirectFunctionCall1(namein, CStringGetDatum(encoding_name)); |
1427 | 0 | } |
1428 | | |
1429 | | /* |
1430 | | * gettext() returns messages in this encoding. This often matches the |
1431 | | * database encoding, but it differs for SQL_ASCII databases, for processes |
1432 | | * not attached to a database. |
1433 | | */ |
1434 | | int |
1435 | | GetMessageEncoding(void) |
1436 | 0 | { |
1437 | 0 | return MessageEncoding->encoding; |
1438 | 0 | } |
1439 | | |
1440 | | |
1441 | | /* |
1442 | | * Generic character incrementer function. |
1443 | | * |
1444 | | * Not knowing anything about the properties of the encoding in use, we just |
1445 | | * keep incrementing the last byte until we get a validly-encoded result, |
1446 | | * or we run out of values to try. We don't bother to try incrementing |
1447 | | * higher-order bytes, so there's no growth in runtime for wider characters. |
1448 | | * (If we did try to do that, we'd need to consider the likelihood that 255 |
1449 | | * is not a valid final byte in the encoding.) |
1450 | | */ |
1451 | | static bool |
1452 | | pg_generic_charinc(unsigned char *charptr, int len) |
1453 | 0 | { |
1454 | 0 | unsigned char *lastbyte = charptr + len - 1; |
1455 | 0 | mbverifychar_function mbverifychar; |
1456 | | |
1457 | | /* We can just invoke the character verifier directly. */ |
1458 | 0 | mbverifychar = pg_wchar_table[GetDatabaseEncoding()].mbverifychar; |
1459 | |
|
1460 | 0 | while (*lastbyte < (unsigned char) 255) |
1461 | 0 | { |
1462 | 0 | (*lastbyte)++; |
1463 | 0 | if ((*mbverifychar) (charptr, len) == len) |
1464 | 0 | return true; |
1465 | 0 | } |
1466 | | |
1467 | 0 | return false; |
1468 | 0 | } |
1469 | | |
1470 | | /* |
1471 | | * UTF-8 character incrementer function. |
1472 | | * |
1473 | | * For a one-byte character less than 0x7F, we just increment the byte. |
1474 | | * |
1475 | | * For a multibyte character, every byte but the first must fall between 0x80 |
1476 | | * and 0xBF; and the first byte must be between 0xC0 and 0xF4. We increment |
1477 | | * the last byte that's not already at its maximum value. If we can't find a |
1478 | | * byte that's less than the maximum allowable value, we simply fail. We also |
1479 | | * need some special-case logic to skip regions used for surrogate pair |
1480 | | * handling, as those should not occur in valid UTF-8. |
1481 | | * |
1482 | | * Note that we don't reset lower-order bytes back to their minimums, since |
1483 | | * we can't afford to make an exhaustive search (see make_greater_string). |
1484 | | */ |
1485 | | static bool |
1486 | | pg_utf8_increment(unsigned char *charptr, int length) |
1487 | 0 | { |
1488 | 0 | unsigned char a; |
1489 | 0 | unsigned char limit; |
1490 | |
|
1491 | 0 | switch (length) |
1492 | 0 | { |
1493 | 0 | default: |
1494 | | /* reject lengths 5 and 6 for now */ |
1495 | 0 | return false; |
1496 | 0 | case 4: |
1497 | 0 | a = charptr[3]; |
1498 | 0 | if (a < 0xBF) |
1499 | 0 | { |
1500 | 0 | charptr[3]++; |
1501 | 0 | break; |
1502 | 0 | } |
1503 | 0 | pg_fallthrough; |
1504 | 0 | case 3: |
1505 | 0 | a = charptr[2]; |
1506 | 0 | if (a < 0xBF) |
1507 | 0 | { |
1508 | 0 | charptr[2]++; |
1509 | 0 | break; |
1510 | 0 | } |
1511 | 0 | pg_fallthrough; |
1512 | 0 | case 2: |
1513 | 0 | a = charptr[1]; |
1514 | 0 | switch (*charptr) |
1515 | 0 | { |
1516 | 0 | case 0xED: |
1517 | 0 | limit = 0x9F; |
1518 | 0 | break; |
1519 | 0 | case 0xF4: |
1520 | 0 | limit = 0x8F; |
1521 | 0 | break; |
1522 | 0 | default: |
1523 | 0 | limit = 0xBF; |
1524 | 0 | break; |
1525 | 0 | } |
1526 | 0 | if (a < limit) |
1527 | 0 | { |
1528 | 0 | charptr[1]++; |
1529 | 0 | break; |
1530 | 0 | } |
1531 | 0 | pg_fallthrough; |
1532 | 0 | case 1: |
1533 | 0 | a = *charptr; |
1534 | 0 | if (a == 0x7F || a == 0xDF || a == 0xEF || a == 0xF4) |
1535 | 0 | return false; |
1536 | 0 | charptr[0]++; |
1537 | 0 | break; |
1538 | 0 | } |
1539 | | |
1540 | 0 | return true; |
1541 | 0 | } |
1542 | | |
1543 | | /* |
1544 | | * EUC-JP character incrementer function. |
1545 | | * |
1546 | | * If the sequence starts with SS2 (0x8e), it must be a two-byte sequence |
1547 | | * representing JIS X 0201 characters with the second byte ranging between |
1548 | | * 0xa1 and 0xdf. We just increment the last byte if it's less than 0xdf, |
1549 | | * and otherwise rewrite the whole sequence to 0xa1 0xa1. |
1550 | | * |
1551 | | * If the sequence starts with SS3 (0x8f), it must be a three-byte sequence |
1552 | | * in which the last two bytes range between 0xa1 and 0xfe. The last byte |
1553 | | * is incremented if possible, otherwise the second-to-last byte. |
1554 | | * |
1555 | | * If the sequence starts with a value other than the above and its MSB |
1556 | | * is set, it must be a two-byte sequence representing JIS X 0208 characters |
1557 | | * with both bytes ranging between 0xa1 and 0xfe. The last byte is |
1558 | | * incremented if possible, otherwise the second-to-last byte. |
1559 | | * |
1560 | | * Otherwise, the sequence is a single-byte ASCII character. It is |
1561 | | * incremented up to 0x7f. |
1562 | | */ |
1563 | | static bool |
1564 | | pg_eucjp_increment(unsigned char *charptr, int length) |
1565 | 0 | { |
1566 | 0 | unsigned char c1, |
1567 | 0 | c2; |
1568 | 0 | int i; |
1569 | |
|
1570 | 0 | c1 = *charptr; |
1571 | |
|
1572 | 0 | switch (c1) |
1573 | 0 | { |
1574 | 0 | case SS2: /* JIS X 0201 */ |
1575 | 0 | if (length != 2) |
1576 | 0 | return false; |
1577 | | |
1578 | 0 | c2 = charptr[1]; |
1579 | |
|
1580 | 0 | if (c2 >= 0xdf) |
1581 | 0 | charptr[0] = charptr[1] = 0xa1; |
1582 | 0 | else if (c2 < 0xa1) |
1583 | 0 | charptr[1] = 0xa1; |
1584 | 0 | else |
1585 | 0 | charptr[1]++; |
1586 | 0 | break; |
1587 | | |
1588 | 0 | case SS3: /* JIS X 0212 */ |
1589 | 0 | if (length != 3) |
1590 | 0 | return false; |
1591 | | |
1592 | 0 | for (i = 2; i > 0; i--) |
1593 | 0 | { |
1594 | 0 | c2 = charptr[i]; |
1595 | 0 | if (c2 < 0xa1) |
1596 | 0 | { |
1597 | 0 | charptr[i] = 0xa1; |
1598 | 0 | return true; |
1599 | 0 | } |
1600 | 0 | else if (c2 < 0xfe) |
1601 | 0 | { |
1602 | 0 | charptr[i]++; |
1603 | 0 | return true; |
1604 | 0 | } |
1605 | 0 | } |
1606 | | |
1607 | | /* Out of 3-byte code region */ |
1608 | 0 | return false; |
1609 | | |
1610 | 0 | default: |
1611 | 0 | if (IS_HIGHBIT_SET(c1)) /* JIS X 0208? */ |
1612 | 0 | { |
1613 | 0 | if (length != 2) |
1614 | 0 | return false; |
1615 | | |
1616 | 0 | for (i = 1; i >= 0; i--) |
1617 | 0 | { |
1618 | 0 | c2 = charptr[i]; |
1619 | 0 | if (c2 < 0xa1) |
1620 | 0 | { |
1621 | 0 | charptr[i] = 0xa1; |
1622 | 0 | return true; |
1623 | 0 | } |
1624 | 0 | else if (c2 < 0xfe) |
1625 | 0 | { |
1626 | 0 | charptr[i]++; |
1627 | 0 | return true; |
1628 | 0 | } |
1629 | 0 | } |
1630 | | |
1631 | | /* Out of 2 byte code region */ |
1632 | 0 | return false; |
1633 | 0 | } |
1634 | 0 | else |
1635 | 0 | { /* ASCII, single byte */ |
1636 | 0 | if (c1 > 0x7e) |
1637 | 0 | return false; |
1638 | 0 | (*charptr)++; |
1639 | 0 | } |
1640 | 0 | break; |
1641 | 0 | } |
1642 | | |
1643 | 0 | return true; |
1644 | 0 | } |
1645 | | |
1646 | | /* |
1647 | | * get the character incrementer for the encoding for the current database |
1648 | | */ |
1649 | | mbcharacter_incrementer |
1650 | | pg_database_encoding_character_incrementer(void) |
1651 | 0 | { |
1652 | | /* |
1653 | | * Eventually it might be best to add a field to pg_wchar_table[], but for |
1654 | | * now we just use a switch. |
1655 | | */ |
1656 | 0 | switch (GetDatabaseEncoding()) |
1657 | 0 | { |
1658 | 0 | case PG_UTF8: |
1659 | 0 | return pg_utf8_increment; |
1660 | | |
1661 | 0 | case PG_EUC_JP: |
1662 | 0 | return pg_eucjp_increment; |
1663 | | |
1664 | 0 | default: |
1665 | 0 | return pg_generic_charinc; |
1666 | 0 | } |
1667 | 0 | } |
1668 | | |
1669 | | /* |
1670 | | * fetch maximum length of the encoding for the current database |
1671 | | */ |
1672 | | int |
1673 | | pg_database_encoding_max_length(void) |
1674 | 3.86M | { |
1675 | 3.86M | return pg_wchar_table[GetDatabaseEncoding()].maxmblen; |
1676 | 3.86M | } |
1677 | | |
1678 | | /* |
1679 | | * Verify mbstr to make sure that it is validly encoded in the current |
1680 | | * database encoding. Otherwise same as pg_verify_mbstr(). |
1681 | | */ |
1682 | | bool |
1683 | | pg_verifymbstr(const char *mbstr, int len, bool noError) |
1684 | 365 | { |
1685 | 365 | return pg_verify_mbstr(GetDatabaseEncoding(), mbstr, len, noError); |
1686 | 365 | } |
1687 | | |
1688 | | /* |
1689 | | * Verify mbstr to make sure that it is validly encoded in the specified |
1690 | | * encoding. |
1691 | | */ |
1692 | | bool |
1693 | | pg_verify_mbstr(int encoding, const char *mbstr, int len, bool noError) |
1694 | 365 | { |
1695 | 365 | int oklen; |
1696 | | |
1697 | 365 | Assert(PG_VALID_ENCODING(encoding)); |
1698 | | |
1699 | 365 | oklen = pg_wchar_table[encoding].mbverifystr((const unsigned char *) mbstr, len); |
1700 | 365 | if (oklen != len) |
1701 | 54 | { |
1702 | 54 | if (noError) |
1703 | 0 | return false; |
1704 | 54 | report_invalid_encoding(encoding, mbstr + oklen, len - oklen); |
1705 | 54 | } |
1706 | 365 | return true; |
1707 | 365 | } |
1708 | | |
1709 | | /* |
1710 | | * Verify mbstr to make sure that it is validly encoded in the specified |
1711 | | * encoding. |
1712 | | * |
1713 | | * mbstr is not necessarily zero terminated; length of mbstr is |
1714 | | * specified by len. |
1715 | | * |
1716 | | * If OK, return length of string in the encoding. |
1717 | | * If a problem is found, return -1 when noError is |
1718 | | * true; when noError is false, ereport() a descriptive message. |
1719 | | * |
1720 | | * Note: We cannot use the faster encoding-specific mbverifystr() function |
1721 | | * here, because we need to count the number of characters in the string. |
1722 | | */ |
1723 | | int |
1724 | | pg_verify_mbstr_len(int encoding, const char *mbstr, int len, bool noError) |
1725 | 0 | { |
1726 | 0 | mbverifychar_function mbverifychar; |
1727 | 0 | int mb_len; |
1728 | |
|
1729 | 0 | Assert(PG_VALID_ENCODING(encoding)); |
1730 | | |
1731 | | /* |
1732 | | * In single-byte encodings, we need only reject nulls (\0). |
1733 | | */ |
1734 | 0 | if (pg_encoding_max_length(encoding) <= 1) |
1735 | 0 | { |
1736 | 0 | const char *nullpos = memchr(mbstr, 0, len); |
1737 | |
|
1738 | 0 | if (nullpos == NULL) |
1739 | 0 | return len; |
1740 | 0 | if (noError) |
1741 | 0 | return -1; |
1742 | 0 | report_invalid_encoding(encoding, nullpos, 1); |
1743 | 0 | } |
1744 | | |
1745 | | /* fetch function pointer just once */ |
1746 | 0 | mbverifychar = pg_wchar_table[encoding].mbverifychar; |
1747 | |
|
1748 | 0 | mb_len = 0; |
1749 | |
|
1750 | 0 | while (len > 0) |
1751 | 0 | { |
1752 | 0 | int l; |
1753 | | |
1754 | | /* fast path for ASCII-subset characters */ |
1755 | 0 | if (!IS_HIGHBIT_SET(*mbstr)) |
1756 | 0 | { |
1757 | 0 | if (*mbstr != '\0') |
1758 | 0 | { |
1759 | 0 | mb_len++; |
1760 | 0 | mbstr++; |
1761 | 0 | len--; |
1762 | 0 | continue; |
1763 | 0 | } |
1764 | 0 | if (noError) |
1765 | 0 | return -1; |
1766 | 0 | report_invalid_encoding(encoding, mbstr, len); |
1767 | 0 | } |
1768 | | |
1769 | 0 | l = (*mbverifychar) ((const unsigned char *) mbstr, len); |
1770 | |
|
1771 | 0 | if (l < 0) |
1772 | 0 | { |
1773 | 0 | if (noError) |
1774 | 0 | return -1; |
1775 | 0 | report_invalid_encoding(encoding, mbstr, len); |
1776 | 0 | } |
1777 | | |
1778 | 0 | mbstr += l; |
1779 | 0 | len -= l; |
1780 | 0 | mb_len++; |
1781 | 0 | } |
1782 | 0 | return mb_len; |
1783 | 0 | } |
1784 | | |
1785 | | /* |
1786 | | * check_encoding_conversion_args: check arguments of a conversion function |
1787 | | * |
1788 | | * "expected" arguments can be either an encoding ID or -1 to indicate that |
1789 | | * the caller will check whether it accepts the ID. |
1790 | | * |
1791 | | * Note: the errors here are not really user-facing, so elog instead of |
1792 | | * ereport seems sufficient. Also, we trust that the "expected" encoding |
1793 | | * arguments are valid encoding IDs, but we don't trust the actuals. |
1794 | | */ |
1795 | | void |
1796 | | check_encoding_conversion_args(int src_encoding, |
1797 | | int dest_encoding, |
1798 | | int len, |
1799 | | int expected_src_encoding, |
1800 | | int expected_dest_encoding) |
1801 | 0 | { |
1802 | 0 | if (!PG_VALID_ENCODING(src_encoding)) |
1803 | 0 | elog(ERROR, "invalid source encoding ID: %d", src_encoding); |
1804 | 0 | if (src_encoding != expected_src_encoding && expected_src_encoding >= 0) |
1805 | 0 | elog(ERROR, "expected source encoding \"%s\", but got \"%s\"", |
1806 | 0 | pg_enc2name_tbl[expected_src_encoding].name, |
1807 | 0 | pg_enc2name_tbl[src_encoding].name); |
1808 | 0 | if (!PG_VALID_ENCODING(dest_encoding)) |
1809 | 0 | elog(ERROR, "invalid destination encoding ID: %d", dest_encoding); |
1810 | 0 | if (dest_encoding != expected_dest_encoding && expected_dest_encoding >= 0) |
1811 | 0 | elog(ERROR, "expected destination encoding \"%s\", but got \"%s\"", |
1812 | 0 | pg_enc2name_tbl[expected_dest_encoding].name, |
1813 | 0 | pg_enc2name_tbl[dest_encoding].name); |
1814 | 0 | if (len < 0) |
1815 | 0 | elog(ERROR, "encoding conversion length must not be negative"); |
1816 | 0 | } |
1817 | | |
1818 | | /* |
1819 | | * report_invalid_encoding: complain about invalid multibyte character |
1820 | | * |
1821 | | * note: len is remaining length of string, not length of character; |
1822 | | * len must be greater than zero (or we'd neglect initializing "buf"). |
1823 | | */ |
1824 | | void |
1825 | | report_invalid_encoding(int encoding, const char *mbstr, int len) |
1826 | 54 | { |
1827 | 54 | int l = pg_encoding_mblen_or_incomplete(encoding, mbstr, len); |
1828 | | |
1829 | 54 | report_invalid_encoding_int(encoding, mbstr, l, len); |
1830 | 54 | } |
1831 | | |
1832 | | static void |
1833 | | report_invalid_encoding_int(int encoding, const char *mbstr, int mblen, int len) |
1834 | 54 | { |
1835 | 54 | char buf[8 * 5 + 1]; |
1836 | 54 | char *p = buf; |
1837 | 54 | int j, |
1838 | 54 | jlimit; |
1839 | | |
1840 | 54 | jlimit = Min(mblen, len); |
1841 | 54 | jlimit = Min(jlimit, 8); /* prevent buffer overrun */ |
1842 | | |
1843 | 108 | for (j = 0; j < jlimit; j++) |
1844 | 54 | { |
1845 | 54 | p += sprintf(p, "0x%02x", (unsigned char) mbstr[j]); |
1846 | 54 | if (j < jlimit - 1) |
1847 | 0 | p += sprintf(p, " "); |
1848 | 54 | } |
1849 | | |
1850 | 54 | ereport(ERROR, |
1851 | 54 | (errcode(ERRCODE_CHARACTER_NOT_IN_REPERTOIRE), |
1852 | 54 | errmsg("invalid byte sequence for encoding \"%s\": %s", |
1853 | 54 | pg_enc2name_tbl[encoding].name, |
1854 | 54 | buf))); |
1855 | 54 | } |
1856 | | |
1857 | | static void |
1858 | | report_invalid_encoding_db(const char *mbstr, int mblen, int len) |
1859 | 0 | { |
1860 | 0 | report_invalid_encoding_int(GetDatabaseEncoding(), mbstr, mblen, len); |
1861 | 0 | } |
1862 | | |
1863 | | /* |
1864 | | * report_untranslatable_char: complain about untranslatable character |
1865 | | * |
1866 | | * note: len is remaining length of string, not length of character; |
1867 | | * len must be greater than zero (or we'd neglect initializing "buf"). |
1868 | | */ |
1869 | | void |
1870 | | report_untranslatable_char(int src_encoding, int dest_encoding, |
1871 | | const char *mbstr, int len) |
1872 | 0 | { |
1873 | 0 | int l; |
1874 | 0 | char buf[8 * 5 + 1]; |
1875 | 0 | char *p = buf; |
1876 | 0 | int j, |
1877 | 0 | jlimit; |
1878 | | |
1879 | | /* |
1880 | | * We probably could use plain pg_encoding_mblen(), because |
1881 | | * gb18030_to_utf8() verifies before it converts. All conversions should. |
1882 | | * For src_encoding!=GB18030, len>0 meets pg_encoding_mblen() needs. Even |
1883 | | * so, be defensive, since a buggy conversion might pass invalid data. |
1884 | | * This is not a performance-critical path. |
1885 | | */ |
1886 | 0 | l = pg_encoding_mblen_or_incomplete(src_encoding, mbstr, len); |
1887 | 0 | jlimit = Min(l, len); |
1888 | 0 | jlimit = Min(jlimit, 8); /* prevent buffer overrun */ |
1889 | |
|
1890 | 0 | for (j = 0; j < jlimit; j++) |
1891 | 0 | { |
1892 | 0 | p += sprintf(p, "0x%02x", (unsigned char) mbstr[j]); |
1893 | 0 | if (j < jlimit - 1) |
1894 | 0 | p += sprintf(p, " "); |
1895 | 0 | } |
1896 | |
|
1897 | 0 | ereport(ERROR, |
1898 | 0 | (errcode(ERRCODE_UNTRANSLATABLE_CHARACTER), |
1899 | 0 | errmsg("character with byte sequence %s in encoding \"%s\" has no equivalent in encoding \"%s\"", |
1900 | 0 | buf, |
1901 | 0 | pg_enc2name_tbl[src_encoding].name, |
1902 | 0 | pg_enc2name_tbl[dest_encoding].name))); |
1903 | 0 | } |
1904 | | |
1905 | | |
1906 | | #ifdef WIN32 |
1907 | | /* |
1908 | | * Convert from MessageEncoding to a palloc'ed, null-terminated utf16 |
1909 | | * string. The character length is also passed to utf16len if not |
1910 | | * null. Returns NULL iff failed. Before MessageEncoding initialization, "str" |
1911 | | * should be ASCII-only; this will function as though MessageEncoding is UTF8. |
1912 | | */ |
1913 | | WCHAR * |
1914 | | pgwin32_message_to_UTF16(const char *str, int len, int *utf16len) |
1915 | | { |
1916 | | int msgenc = GetMessageEncoding(); |
1917 | | WCHAR *utf16; |
1918 | | int dstlen; |
1919 | | UINT codepage; |
1920 | | |
1921 | | if (msgenc == PG_SQL_ASCII) |
1922 | | /* No conversion is possible, and SQL_ASCII is never utf16. */ |
1923 | | return NULL; |
1924 | | |
1925 | | codepage = pg_enc2name_tbl[msgenc].codepage; |
1926 | | |
1927 | | /* |
1928 | | * Use MultiByteToWideChar directly if there is a corresponding codepage, |
1929 | | * or double conversion through UTF8 if not. Double conversion is needed, |
1930 | | * for example, in an ENCODING=LATIN8, LC_CTYPE=C database. |
1931 | | */ |
1932 | | if (codepage != 0) |
1933 | | { |
1934 | | utf16 = palloc_array(WCHAR, len + 1); |
1935 | | dstlen = MultiByteToWideChar(codepage, 0, str, len, utf16, len); |
1936 | | utf16[dstlen] = (WCHAR) 0; |
1937 | | } |
1938 | | else |
1939 | | { |
1940 | | char *utf8; |
1941 | | |
1942 | | /* |
1943 | | * XXX pg_do_encoding_conversion() requires a transaction. In the |
1944 | | * absence of one, hope for the input to be valid UTF8. |
1945 | | */ |
1946 | | if (IsTransactionState()) |
1947 | | { |
1948 | | utf8 = (char *) pg_do_encoding_conversion((unsigned char *) unconstify(char *, str), |
1949 | | len, |
1950 | | msgenc, |
1951 | | PG_UTF8); |
1952 | | if (utf8 != str) |
1953 | | len = strlen(utf8); |
1954 | | } |
1955 | | else |
1956 | | utf8 = unconstify(char *, str); |
1957 | | |
1958 | | utf16 = palloc_array(WCHAR, len + 1); |
1959 | | dstlen = MultiByteToWideChar(CP_UTF8, 0, utf8, len, utf16, len); |
1960 | | utf16[dstlen] = (WCHAR) 0; |
1961 | | |
1962 | | if (utf8 != str) |
1963 | | pfree(utf8); |
1964 | | } |
1965 | | |
1966 | | if (dstlen == 0 && len > 0) |
1967 | | { |
1968 | | pfree(utf16); |
1969 | | return NULL; /* error */ |
1970 | | } |
1971 | | |
1972 | | if (utf16len) |
1973 | | *utf16len = dstlen; |
1974 | | return utf16; |
1975 | | } |
1976 | | |
1977 | | #endif /* WIN32 */ |