mirror of
https://github.com/postgres/postgres.git
synced 2025-12-22 17:42:17 +03:00
Convert a few more datatype input functions to report errors softly.
Convert bit_in, varbit_in, inet_in, cidr_in, macaddr_in, and macaddr8_in to the new style. Amul Sul, minor mods by me Discussion: https://postgr.es/m/CAAJ_b97KeDWUdpTKGOaFYPv0OicjOu6EW+QYWj-Ywrgj_aEy1g@mail.gmail.com
This commit is contained in:
@@ -55,6 +55,7 @@ Datum
|
||||
macaddr_in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *str = PG_GETARG_CSTRING(0);
|
||||
Node *escontext = fcinfo->context;
|
||||
macaddr *result;
|
||||
int a,
|
||||
b,
|
||||
@@ -88,7 +89,7 @@ macaddr_in(PG_FUNCTION_ARGS)
|
||||
count = sscanf(str, "%2x%2x%2x%2x%2x%2x%1s",
|
||||
&a, &b, &c, &d, &e, &f, junk);
|
||||
if (count != 6)
|
||||
ereport(ERROR,
|
||||
ereturn(escontext, (Datum) 0,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type %s: \"%s\"", "macaddr",
|
||||
str)));
|
||||
@@ -96,7 +97,7 @@ macaddr_in(PG_FUNCTION_ARGS)
|
||||
if ((a < 0) || (a > 255) || (b < 0) || (b > 255) ||
|
||||
(c < 0) || (c > 255) || (d < 0) || (d > 255) ||
|
||||
(e < 0) || (e > 255) || (f < 0) || (f > 255))
|
||||
ereport(ERROR,
|
||||
ereturn(escontext, (Datum) 0,
|
||||
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
|
||||
errmsg("invalid octet value in \"macaddr\" value: \"%s\"", str)));
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#define lobits(addr) \
|
||||
((unsigned long)(((addr)->e<<24) | ((addr)->f<<16) | ((addr)->g<<8) | ((addr)->h)))
|
||||
|
||||
static unsigned char hex2_to_uchar(const unsigned char *ptr, const unsigned char *str);
|
||||
static unsigned char hex2_to_uchar(const unsigned char *ptr, bool *badhex);
|
||||
|
||||
static const signed char hexlookup[128] = {
|
||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||
@@ -51,16 +51,13 @@ static const signed char hexlookup[128] = {
|
||||
/*
|
||||
* hex2_to_uchar - convert 2 hex digits to a byte (unsigned char)
|
||||
*
|
||||
* This will ereport() if the end of the string is reached ('\0' found), or if
|
||||
* Sets *badhex to true if the end of the string is reached ('\0' found), or if
|
||||
* either character is not a valid hex digit.
|
||||
*
|
||||
* ptr is the pointer to where the digits to convert are in the string, str is
|
||||
* the entire string, which is used only for error reporting.
|
||||
*/
|
||||
static inline unsigned char
|
||||
hex2_to_uchar(const unsigned char *ptr, const unsigned char *str)
|
||||
hex2_to_uchar(const unsigned char *ptr, bool *badhex)
|
||||
{
|
||||
unsigned char ret = 0;
|
||||
unsigned char ret;
|
||||
signed char lookup;
|
||||
|
||||
/* Handle the first character */
|
||||
@@ -88,12 +85,7 @@ hex2_to_uchar(const unsigned char *ptr, const unsigned char *str)
|
||||
return ret;
|
||||
|
||||
invalid_input:
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
|
||||
str)));
|
||||
|
||||
/* We do not actually reach here */
|
||||
*badhex = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -104,7 +96,9 @@ Datum
|
||||
macaddr8_in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
const unsigned char *str = (unsigned char *) PG_GETARG_CSTRING(0);
|
||||
Node *escontext = fcinfo->context;
|
||||
const unsigned char *ptr = str;
|
||||
bool badhex = false;
|
||||
macaddr8 *result;
|
||||
unsigned char a = 0,
|
||||
b = 0,
|
||||
@@ -136,37 +130,37 @@ macaddr8_in(PG_FUNCTION_ARGS)
|
||||
switch (count)
|
||||
{
|
||||
case 1:
|
||||
a = hex2_to_uchar(ptr, str);
|
||||
a = hex2_to_uchar(ptr, &badhex);
|
||||
break;
|
||||
case 2:
|
||||
b = hex2_to_uchar(ptr, str);
|
||||
b = hex2_to_uchar(ptr, &badhex);
|
||||
break;
|
||||
case 3:
|
||||
c = hex2_to_uchar(ptr, str);
|
||||
c = hex2_to_uchar(ptr, &badhex);
|
||||
break;
|
||||
case 4:
|
||||
d = hex2_to_uchar(ptr, str);
|
||||
d = hex2_to_uchar(ptr, &badhex);
|
||||
break;
|
||||
case 5:
|
||||
e = hex2_to_uchar(ptr, str);
|
||||
e = hex2_to_uchar(ptr, &badhex);
|
||||
break;
|
||||
case 6:
|
||||
f = hex2_to_uchar(ptr, str);
|
||||
f = hex2_to_uchar(ptr, &badhex);
|
||||
break;
|
||||
case 7:
|
||||
g = hex2_to_uchar(ptr, str);
|
||||
g = hex2_to_uchar(ptr, &badhex);
|
||||
break;
|
||||
case 8:
|
||||
h = hex2_to_uchar(ptr, str);
|
||||
h = hex2_to_uchar(ptr, &badhex);
|
||||
break;
|
||||
default:
|
||||
/* must be trailing garbage... */
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
|
||||
str)));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (badhex)
|
||||
goto fail;
|
||||
|
||||
/* Move forward to where the next byte should be */
|
||||
ptr += 2;
|
||||
|
||||
@@ -179,10 +173,7 @@ macaddr8_in(PG_FUNCTION_ARGS)
|
||||
|
||||
/* Have to use the same spacer throughout */
|
||||
else if (spacer != *ptr)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
|
||||
str)));
|
||||
goto fail;
|
||||
|
||||
/* move past the spacer */
|
||||
ptr++;
|
||||
@@ -197,10 +188,7 @@ macaddr8_in(PG_FUNCTION_ARGS)
|
||||
|
||||
/* If we found a space and then non-space, it's invalid */
|
||||
if (*ptr)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
|
||||
str)));
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -216,10 +204,7 @@ macaddr8_in(PG_FUNCTION_ARGS)
|
||||
e = 0xFE;
|
||||
}
|
||||
else if (count != 8)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
|
||||
str)));
|
||||
goto fail;
|
||||
|
||||
result = (macaddr8 *) palloc0(sizeof(macaddr8));
|
||||
|
||||
@@ -233,6 +218,12 @@ macaddr8_in(PG_FUNCTION_ARGS)
|
||||
result->h = h;
|
||||
|
||||
PG_RETURN_MACADDR8_P(result);
|
||||
|
||||
fail:
|
||||
ereturn(escontext, (Datum) 0,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
|
||||
str)));
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -72,7 +72,7 @@ static inet *internal_inetpl(inet *ip, int64 addend);
|
||||
* Common INET/CIDR input routine
|
||||
*/
|
||||
static inet *
|
||||
network_in(char *src, bool is_cidr)
|
||||
network_in(char *src, bool is_cidr, Node *escontext)
|
||||
{
|
||||
int bits;
|
||||
inet *dst;
|
||||
@@ -93,7 +93,7 @@ network_in(char *src, bool is_cidr)
|
||||
bits = pg_inet_net_pton(ip_family(dst), src, ip_addr(dst),
|
||||
is_cidr ? ip_addrsize(dst) : -1);
|
||||
if ((bits < 0) || (bits > ip_maxbits(dst)))
|
||||
ereport(ERROR,
|
||||
ereturn(escontext, NULL,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
/* translator: first %s is inet or cidr */
|
||||
errmsg("invalid input syntax for type %s: \"%s\"",
|
||||
@@ -105,7 +105,7 @@ network_in(char *src, bool is_cidr)
|
||||
if (is_cidr)
|
||||
{
|
||||
if (!addressOK(ip_addr(dst), bits, ip_family(dst)))
|
||||
ereport(ERROR,
|
||||
ereturn(escontext, NULL,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("invalid cidr value: \"%s\"", src),
|
||||
errdetail("Value has bits set to right of mask.")));
|
||||
@@ -122,7 +122,7 @@ inet_in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *src = PG_GETARG_CSTRING(0);
|
||||
|
||||
PG_RETURN_INET_P(network_in(src, false));
|
||||
PG_RETURN_INET_P(network_in(src, false, fcinfo->context));
|
||||
}
|
||||
|
||||
Datum
|
||||
@@ -130,7 +130,7 @@ cidr_in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *src = PG_GETARG_CSTRING(0);
|
||||
|
||||
PG_RETURN_INET_P(network_in(src, true));
|
||||
PG_RETURN_INET_P(network_in(src, true, fcinfo->context));
|
||||
}
|
||||
|
||||
|
||||
@@ -1742,7 +1742,7 @@ inet_client_addr(PG_FUNCTION_ARGS)
|
||||
|
||||
clean_ipv6_addr(port->raddr.addr.ss_family, remote_host);
|
||||
|
||||
PG_RETURN_INET_P(network_in(remote_host, false));
|
||||
PG_RETURN_INET_P(network_in(remote_host, false, NULL));
|
||||
}
|
||||
|
||||
|
||||
@@ -1814,7 +1814,7 @@ inet_server_addr(PG_FUNCTION_ARGS)
|
||||
|
||||
clean_ipv6_addr(port->laddr.addr.ss_family, local_host);
|
||||
|
||||
PG_RETURN_INET_P(network_in(local_host, false));
|
||||
PG_RETURN_INET_P(network_in(local_host, false, NULL));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -147,11 +147,11 @@ Datum
|
||||
bit_in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *input_string = PG_GETARG_CSTRING(0);
|
||||
|
||||
#ifdef NOT_USED
|
||||
Oid typelem = PG_GETARG_OID(1);
|
||||
#endif
|
||||
int32 atttypmod = PG_GETARG_INT32(2);
|
||||
Node *escontext = fcinfo->context;
|
||||
VarBit *result; /* The resulting bit string */
|
||||
char *sp; /* pointer into the character string */
|
||||
bits8 *r; /* pointer into the result */
|
||||
@@ -193,7 +193,7 @@ bit_in(PG_FUNCTION_ARGS)
|
||||
else
|
||||
{
|
||||
if (slen > VARBITMAXLEN / 4)
|
||||
ereport(ERROR,
|
||||
ereturn(escontext, (Datum) 0,
|
||||
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
||||
errmsg("bit string length exceeds the maximum allowed (%d)",
|
||||
VARBITMAXLEN)));
|
||||
@@ -207,7 +207,7 @@ bit_in(PG_FUNCTION_ARGS)
|
||||
if (atttypmod <= 0)
|
||||
atttypmod = bitlen;
|
||||
else if (bitlen != atttypmod)
|
||||
ereport(ERROR,
|
||||
ereturn(escontext, (Datum) 0,
|
||||
(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
|
||||
errmsg("bit string length %d does not match type bit(%d)",
|
||||
bitlen, atttypmod)));
|
||||
@@ -229,7 +229,7 @@ bit_in(PG_FUNCTION_ARGS)
|
||||
if (*sp == '1')
|
||||
*r |= x;
|
||||
else if (*sp != '0')
|
||||
ereport(ERROR,
|
||||
ereturn(escontext, (Datum) 0,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("\"%.*s\" is not a valid binary digit",
|
||||
pg_mblen(sp), sp)));
|
||||
@@ -254,7 +254,7 @@ bit_in(PG_FUNCTION_ARGS)
|
||||
else if (*sp >= 'a' && *sp <= 'f')
|
||||
x = (bits8) (*sp - 'a') + 10;
|
||||
else
|
||||
ereport(ERROR,
|
||||
ereturn(escontext, (Datum) 0,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("\"%.*s\" is not a valid hexadecimal digit",
|
||||
pg_mblen(sp), sp)));
|
||||
@@ -452,11 +452,11 @@ Datum
|
||||
varbit_in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
char *input_string = PG_GETARG_CSTRING(0);
|
||||
|
||||
#ifdef NOT_USED
|
||||
Oid typelem = PG_GETARG_OID(1);
|
||||
#endif
|
||||
int32 atttypmod = PG_GETARG_INT32(2);
|
||||
Node *escontext = fcinfo->context;
|
||||
VarBit *result; /* The resulting bit string */
|
||||
char *sp; /* pointer into the character string */
|
||||
bits8 *r; /* pointer into the result */
|
||||
@@ -494,7 +494,7 @@ varbit_in(PG_FUNCTION_ARGS)
|
||||
else
|
||||
{
|
||||
if (slen > VARBITMAXLEN / 4)
|
||||
ereport(ERROR,
|
||||
ereturn(escontext, (Datum) 0,
|
||||
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
|
||||
errmsg("bit string length exceeds the maximum allowed (%d)",
|
||||
VARBITMAXLEN)));
|
||||
@@ -508,7 +508,7 @@ varbit_in(PG_FUNCTION_ARGS)
|
||||
if (atttypmod <= 0)
|
||||
atttypmod = bitlen;
|
||||
else if (bitlen > atttypmod)
|
||||
ereport(ERROR,
|
||||
ereturn(escontext, (Datum) 0,
|
||||
(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
|
||||
errmsg("bit string too long for type bit varying(%d)",
|
||||
atttypmod)));
|
||||
@@ -530,7 +530,7 @@ varbit_in(PG_FUNCTION_ARGS)
|
||||
if (*sp == '1')
|
||||
*r |= x;
|
||||
else if (*sp != '0')
|
||||
ereport(ERROR,
|
||||
ereturn(escontext, (Datum) 0,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("\"%.*s\" is not a valid binary digit",
|
||||
pg_mblen(sp), sp)));
|
||||
@@ -555,7 +555,7 @@ varbit_in(PG_FUNCTION_ARGS)
|
||||
else if (*sp >= 'a' && *sp <= 'f')
|
||||
x = (bits8) (*sp - 'a') + 10;
|
||||
else
|
||||
ereport(ERROR,
|
||||
ereturn(escontext, (Datum) 0,
|
||||
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
|
||||
errmsg("\"%.*s\" is not a valid hexadecimal digit",
|
||||
pg_mblen(sp), sp)));
|
||||
|
||||
Reference in New Issue
Block a user