mirror of https://github.com/postgres/postgres
Commit 121d2d3d70
included simd.h into pg_wchar.h. This caused a problem
on Windows, since Perl has "#define free" (referring to globals), which
breaks the Windows' header. To fix, move the static inline function
definitions from plperl_helpers.h, into plperl.h, where we already
document the necessary inclusion order. Since those functions were the
only reason for the existence of plperl_helpers.h, remove it.
First reported by Justin Pryzby
Diagnosis and review by Andres Freund, patch by myself per suggestion
from Tom Lane
Discussion: https://www.postgresql.org/message-id/20220826115546.GE2342%40telsasoft.com
pull/103/head
parent
52144b6fcd
commit
4eec2e03c3
@ -1,171 +0,0 @@ |
|||||||
#ifndef PL_PERL_HELPERS_H |
|
||||||
#define PL_PERL_HELPERS_H |
|
||||||
|
|
||||||
#include "mb/pg_wchar.h" |
|
||||||
|
|
||||||
#include "plperl.h" |
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* convert from utf8 to database encoding |
|
||||||
* |
|
||||||
* Returns a palloc'ed copy of the original string |
|
||||||
*/ |
|
||||||
static inline char * |
|
||||||
utf_u2e(char *utf8_str, size_t len) |
|
||||||
{ |
|
||||||
char *ret; |
|
||||||
|
|
||||||
ret = pg_any_to_server(utf8_str, len, PG_UTF8); |
|
||||||
|
|
||||||
/* ensure we have a copy even if no conversion happened */ |
|
||||||
if (ret == utf8_str) |
|
||||||
ret = pstrdup(ret); |
|
||||||
|
|
||||||
return ret; |
|
||||||
} |
|
||||||
|
|
||||||
/*
|
|
||||||
* convert from database encoding to utf8 |
|
||||||
* |
|
||||||
* Returns a palloc'ed copy of the original string |
|
||||||
*/ |
|
||||||
static inline char * |
|
||||||
utf_e2u(const char *str) |
|
||||||
{ |
|
||||||
char *ret; |
|
||||||
|
|
||||||
ret = pg_server_to_any(str, strlen(str), PG_UTF8); |
|
||||||
|
|
||||||
/* ensure we have a copy even if no conversion happened */ |
|
||||||
if (ret == str) |
|
||||||
ret = pstrdup(ret); |
|
||||||
|
|
||||||
return ret; |
|
||||||
} |
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert an SV to a char * in the current database encoding |
|
||||||
* |
|
||||||
* Returns a palloc'ed copy of the original string |
|
||||||
*/ |
|
||||||
static inline char * |
|
||||||
sv2cstr(SV *sv) |
|
||||||
{ |
|
||||||
dTHX; |
|
||||||
char *val, |
|
||||||
*res; |
|
||||||
STRLEN len; |
|
||||||
|
|
||||||
/*
|
|
||||||
* get a utf8 encoded char * out of perl. *note* it may not be valid utf8! |
|
||||||
*/ |
|
||||||
|
|
||||||
/*
|
|
||||||
* SvPVutf8() croaks nastily on certain things, like typeglobs and |
|
||||||
* readonly objects such as $^V. That's a perl bug - it's not supposed to |
|
||||||
* happen. To avoid crashing the backend, we make a copy of the sv before |
|
||||||
* passing it to SvPVutf8(). The copy is garbage collected when we're done |
|
||||||
* with it. |
|
||||||
*/ |
|
||||||
if (SvREADONLY(sv) || |
|
||||||
isGV_with_GP(sv) || |
|
||||||
(SvTYPE(sv) > SVt_PVLV && SvTYPE(sv) != SVt_PVFM)) |
|
||||||
sv = newSVsv(sv); |
|
||||||
else |
|
||||||
{ |
|
||||||
/*
|
|
||||||
* increase the reference count so we can just SvREFCNT_dec() it when |
|
||||||
* we are done |
|
||||||
*/ |
|
||||||
SvREFCNT_inc_simple_void(sv); |
|
||||||
} |
|
||||||
|
|
||||||
/*
|
|
||||||
* Request the string from Perl, in UTF-8 encoding; but if we're in a |
|
||||||
* SQL_ASCII database, just request the byte soup without trying to make |
|
||||||
* it UTF8, because that might fail. |
|
||||||
*/ |
|
||||||
if (GetDatabaseEncoding() == PG_SQL_ASCII) |
|
||||||
val = SvPV(sv, len); |
|
||||||
else |
|
||||||
val = SvPVutf8(sv, len); |
|
||||||
|
|
||||||
/*
|
|
||||||
* Now convert to database encoding. We use perl's length in the event we |
|
||||||
* had an embedded null byte to ensure we error out properly. |
|
||||||
*/ |
|
||||||
res = utf_u2e(val, len); |
|
||||||
|
|
||||||
/* safe now to garbage collect the new SV */ |
|
||||||
SvREFCNT_dec(sv); |
|
||||||
|
|
||||||
return res; |
|
||||||
} |
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a new SV from a string assumed to be in the current database's |
|
||||||
* encoding. |
|
||||||
*/ |
|
||||||
static inline SV * |
|
||||||
cstr2sv(const char *str) |
|
||||||
{ |
|
||||||
dTHX; |
|
||||||
SV *sv; |
|
||||||
char *utf8_str; |
|
||||||
|
|
||||||
/* no conversion when SQL_ASCII */ |
|
||||||
if (GetDatabaseEncoding() == PG_SQL_ASCII) |
|
||||||
return newSVpv(str, 0); |
|
||||||
|
|
||||||
utf8_str = utf_e2u(str); |
|
||||||
|
|
||||||
sv = newSVpv(utf8_str, 0); |
|
||||||
SvUTF8_on(sv); |
|
||||||
pfree(utf8_str); |
|
||||||
|
|
||||||
return sv; |
|
||||||
} |
|
||||||
|
|
||||||
/*
|
|
||||||
* croak() with specified message, which is given in the database encoding. |
|
||||||
* |
|
||||||
* Ideally we'd just write croak("%s", str), but plain croak() does not play |
|
||||||
* nice with non-ASCII data. In modern Perl versions we can call cstr2sv() |
|
||||||
* and pass the result to croak_sv(); in versions that don't have croak_sv(), |
|
||||||
* we have to work harder. |
|
||||||
*/ |
|
||||||
static inline void |
|
||||||
croak_cstr(const char *str) |
|
||||||
{ |
|
||||||
dTHX; |
|
||||||
|
|
||||||
#ifdef croak_sv |
|
||||||
/* Use sv_2mortal() to be sure the transient SV gets freed */ |
|
||||||
croak_sv(sv_2mortal(cstr2sv(str))); |
|
||||||
#else |
|
||||||
|
|
||||||
/*
|
|
||||||
* The older way to do this is to assign a UTF8-marked value to ERRSV and |
|
||||||
* then call croak(NULL). But if we leave it to croak() to append the |
|
||||||
* error location, it does so too late (only after popping the stack) in |
|
||||||
* some Perl versions. Hence, use mess() to create an SV with the error |
|
||||||
* location info already appended. |
|
||||||
*/ |
|
||||||
SV *errsv = get_sv("@", GV_ADD); |
|
||||||
char *utf8_str = utf_e2u(str); |
|
||||||
SV *ssv; |
|
||||||
|
|
||||||
ssv = mess("%s", utf8_str); |
|
||||||
SvUTF8_on(ssv); |
|
||||||
|
|
||||||
pfree(utf8_str); |
|
||||||
|
|
||||||
sv_setsv(errsv, ssv); |
|
||||||
|
|
||||||
croak(NULL); |
|
||||||
#endif /* croak_sv */ |
|
||||||
} |
|
||||||
|
|
||||||
#endif /* PL_PERL_HELPERS_H */ |
|
Loading…
Reference in new issue