Skip to content

Commit 17407a8

Browse files
committed
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
1 parent b18c2de commit 17407a8

File tree

12 files changed

+230
-56
lines changed

12 files changed

+230
-56
lines changed

src/backend/utils/adt/mac.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ Datum
5555
macaddr_in(PG_FUNCTION_ARGS)
5656
{
5757
char *str = PG_GETARG_CSTRING(0);
58+
Node *escontext = fcinfo->context;
5859
macaddr *result;
5960
int a,
6061
b,
@@ -88,15 +89,15 @@ macaddr_in(PG_FUNCTION_ARGS)
8889
count = sscanf(str, "%2x%2x%2x%2x%2x%2x%1s",
8990
&a, &b, &c, &d, &e, &f, junk);
9091
if (count != 6)
91-
ereport(ERROR,
92+
ereturn(escontext, (Datum) 0,
9293
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
9394
errmsg("invalid input syntax for type %s: \"%s\"", "macaddr",
9495
str)));
9596

9697
if ((a < 0) || (a > 255) || (b < 0) || (b > 255) ||
9798
(c < 0) || (c > 255) || (d < 0) || (d > 255) ||
9899
(e < 0) || (e > 255) || (f < 0) || (f > 255))
99-
ereport(ERROR,
100+
ereturn(escontext, (Datum) 0,
100101
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
101102
errmsg("invalid octet value in \"macaddr\" value: \"%s\"", str)));
102103

src/backend/utils/adt/mac8.c

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
#define lobits(addr) \
3636
((unsigned long)(((addr)->e<<24) | ((addr)->f<<16) | ((addr)->g<<8) | ((addr)->h)))
3737

38-
static unsigned char hex2_to_uchar(const unsigned char *ptr, const unsigned char *str);
38+
static unsigned char hex2_to_uchar(const unsigned char *ptr, bool *badhex);
3939

4040
static const signed char hexlookup[128] = {
4141
-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] = {
5151
/*
5252
* hex2_to_uchar - convert 2 hex digits to a byte (unsigned char)
5353
*
54-
* This will ereport() if the end of the string is reached ('\0' found), or if
54+
* Sets *badhex to true if the end of the string is reached ('\0' found), or if
5555
* either character is not a valid hex digit.
56-
*
57-
* ptr is the pointer to where the digits to convert are in the string, str is
58-
* the entire string, which is used only for error reporting.
5956
*/
6057
static inline unsigned char
61-
hex2_to_uchar(const unsigned char *ptr, const unsigned char *str)
58+
hex2_to_uchar(const unsigned char *ptr, bool *badhex)
6259
{
63-
unsigned char ret = 0;
60+
unsigned char ret;
6461
signed char lookup;
6562

6663
/* Handle the first character */
@@ -88,12 +85,7 @@ hex2_to_uchar(const unsigned char *ptr, const unsigned char *str)
8885
return ret;
8986

9087
invalid_input:
91-
ereport(ERROR,
92-
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
93-
errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
94-
str)));
95-
96-
/* We do not actually reach here */
88+
*badhex = true;
9789
return 0;
9890
}
9991

@@ -104,7 +96,9 @@ Datum
10496
macaddr8_in(PG_FUNCTION_ARGS)
10597
{
10698
const unsigned char *str = (unsigned char *) PG_GETARG_CSTRING(0);
99+
Node *escontext = fcinfo->context;
107100
const unsigned char *ptr = str;
101+
bool badhex = false;
108102
macaddr8 *result;
109103
unsigned char a = 0,
110104
b = 0,
@@ -136,37 +130,37 @@ macaddr8_in(PG_FUNCTION_ARGS)
136130
switch (count)
137131
{
138132
case 1:
139-
a = hex2_to_uchar(ptr, str);
133+
a = hex2_to_uchar(ptr, &badhex);
140134
break;
141135
case 2:
142-
b = hex2_to_uchar(ptr, str);
136+
b = hex2_to_uchar(ptr, &badhex);
143137
break;
144138
case 3:
145-
c = hex2_to_uchar(ptr, str);
139+
c = hex2_to_uchar(ptr, &badhex);
146140
break;
147141
case 4:
148-
d = hex2_to_uchar(ptr, str);
142+
d = hex2_to_uchar(ptr, &badhex);
149143
break;
150144
case 5:
151-
e = hex2_to_uchar(ptr, str);
145+
e = hex2_to_uchar(ptr, &badhex);
152146
break;
153147
case 6:
154-
f = hex2_to_uchar(ptr, str);
148+
f = hex2_to_uchar(ptr, &badhex);
155149
break;
156150
case 7:
157-
g = hex2_to_uchar(ptr, str);
151+
g = hex2_to_uchar(ptr, &badhex);
158152
break;
159153
case 8:
160-
h = hex2_to_uchar(ptr, str);
154+
h = hex2_to_uchar(ptr, &badhex);
161155
break;
162156
default:
163157
/* must be trailing garbage... */
164-
ereport(ERROR,
165-
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
166-
errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
167-
str)));
158+
goto fail;
168159
}
169160

161+
if (badhex)
162+
goto fail;
163+
170164
/* Move forward to where the next byte should be */
171165
ptr += 2;
172166

@@ -179,10 +173,7 @@ macaddr8_in(PG_FUNCTION_ARGS)
179173

180174
/* Have to use the same spacer throughout */
181175
else if (spacer != *ptr)
182-
ereport(ERROR,
183-
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
184-
errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
185-
str)));
176+
goto fail;
186177

187178
/* move past the spacer */
188179
ptr++;
@@ -197,10 +188,7 @@ macaddr8_in(PG_FUNCTION_ARGS)
197188

198189
/* If we found a space and then non-space, it's invalid */
199190
if (*ptr)
200-
ereport(ERROR,
201-
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
202-
errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
203-
str)));
191+
goto fail;
204192
}
205193
}
206194
}
@@ -216,10 +204,7 @@ macaddr8_in(PG_FUNCTION_ARGS)
216204
e = 0xFE;
217205
}
218206
else if (count != 8)
219-
ereport(ERROR,
220-
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
221-
errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
222-
str)));
207+
goto fail;
223208

224209
result = (macaddr8 *) palloc0(sizeof(macaddr8));
225210

@@ -233,6 +218,12 @@ macaddr8_in(PG_FUNCTION_ARGS)
233218
result->h = h;
234219

235220
PG_RETURN_MACADDR8_P(result);
221+
222+
fail:
223+
ereturn(escontext, (Datum) 0,
224+
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
225+
errmsg("invalid input syntax for type %s: \"%s\"", "macaddr8",
226+
str)));
236227
}
237228

238229
/*

src/backend/utils/adt/network.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ static inet *internal_inetpl(inet *ip, int64 addend);
7272
* Common INET/CIDR input routine
7373
*/
7474
static inet *
75-
network_in(char *src, bool is_cidr)
75+
network_in(char *src, bool is_cidr, Node *escontext)
7676
{
7777
int bits;
7878
inet *dst;
@@ -93,7 +93,7 @@ network_in(char *src, bool is_cidr)
9393
bits = pg_inet_net_pton(ip_family(dst), src, ip_addr(dst),
9494
is_cidr ? ip_addrsize(dst) : -1);
9595
if ((bits < 0) || (bits > ip_maxbits(dst)))
96-
ereport(ERROR,
96+
ereturn(escontext, NULL,
9797
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
9898
/* translator: first %s is inet or cidr */
9999
errmsg("invalid input syntax for type %s: \"%s\"",
@@ -105,7 +105,7 @@ network_in(char *src, bool is_cidr)
105105
if (is_cidr)
106106
{
107107
if (!addressOK(ip_addr(dst), bits, ip_family(dst)))
108-
ereport(ERROR,
108+
ereturn(escontext, NULL,
109109
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
110110
errmsg("invalid cidr value: \"%s\"", src),
111111
errdetail("Value has bits set to right of mask.")));
@@ -122,15 +122,15 @@ inet_in(PG_FUNCTION_ARGS)
122122
{
123123
char *src = PG_GETARG_CSTRING(0);
124124

125-
PG_RETURN_INET_P(network_in(src, false));
125+
PG_RETURN_INET_P(network_in(src, false, fcinfo->context));
126126
}
127127

128128
Datum
129129
cidr_in(PG_FUNCTION_ARGS)
130130
{
131131
char *src = PG_GETARG_CSTRING(0);
132132

133-
PG_RETURN_INET_P(network_in(src, true));
133+
PG_RETURN_INET_P(network_in(src, true, fcinfo->context));
134134
}
135135

136136

@@ -1742,7 +1742,7 @@ inet_client_addr(PG_FUNCTION_ARGS)
17421742

17431743
clean_ipv6_addr(port->raddr.addr.ss_family, remote_host);
17441744

1745-
PG_RETURN_INET_P(network_in(remote_host, false));
1745+
PG_RETURN_INET_P(network_in(remote_host, false, NULL));
17461746
}
17471747

17481748

@@ -1814,7 +1814,7 @@ inet_server_addr(PG_FUNCTION_ARGS)
18141814

18151815
clean_ipv6_addr(port->laddr.addr.ss_family, local_host);
18161816

1817-
PG_RETURN_INET_P(network_in(local_host, false));
1817+
PG_RETURN_INET_P(network_in(local_host, false, NULL));
18181818
}
18191819

18201820

src/backend/utils/adt/varbit.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -147,11 +147,11 @@ Datum
147147
bit_in(PG_FUNCTION_ARGS)
148148
{
149149
char *input_string = PG_GETARG_CSTRING(0);
150-
151150
#ifdef NOT_USED
152151
Oid typelem = PG_GETARG_OID(1);
153152
#endif
154153
int32 atttypmod = PG_GETARG_INT32(2);
154+
Node *escontext = fcinfo->context;
155155
VarBit *result; /* The resulting bit string */
156156
char *sp; /* pointer into the character string */
157157
bits8 *r; /* pointer into the result */
@@ -193,7 +193,7 @@ bit_in(PG_FUNCTION_ARGS)
193193
else
194194
{
195195
if (slen > VARBITMAXLEN / 4)
196-
ereport(ERROR,
196+
ereturn(escontext, (Datum) 0,
197197
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
198198
errmsg("bit string length exceeds the maximum allowed (%d)",
199199
VARBITMAXLEN)));
@@ -207,7 +207,7 @@ bit_in(PG_FUNCTION_ARGS)
207207
if (atttypmod <= 0)
208208
atttypmod = bitlen;
209209
else if (bitlen != atttypmod)
210-
ereport(ERROR,
210+
ereturn(escontext, (Datum) 0,
211211
(errcode(ERRCODE_STRING_DATA_LENGTH_MISMATCH),
212212
errmsg("bit string length %d does not match type bit(%d)",
213213
bitlen, atttypmod)));
@@ -229,7 +229,7 @@ bit_in(PG_FUNCTION_ARGS)
229229
if (*sp == '1')
230230
*r |= x;
231231
else if (*sp != '0')
232-
ereport(ERROR,
232+
ereturn(escontext, (Datum) 0,
233233
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
234234
errmsg("\"%.*s\" is not a valid binary digit",
235235
pg_mblen(sp), sp)));
@@ -254,7 +254,7 @@ bit_in(PG_FUNCTION_ARGS)
254254
else if (*sp >= 'a' && *sp <= 'f')
255255
x = (bits8) (*sp - 'a') + 10;
256256
else
257-
ereport(ERROR,
257+
ereturn(escontext, (Datum) 0,
258258
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
259259
errmsg("\"%.*s\" is not a valid hexadecimal digit",
260260
pg_mblen(sp), sp)));
@@ -452,11 +452,11 @@ Datum
452452
varbit_in(PG_FUNCTION_ARGS)
453453
{
454454
char *input_string = PG_GETARG_CSTRING(0);
455-
456455
#ifdef NOT_USED
457456
Oid typelem = PG_GETARG_OID(1);
458457
#endif
459458
int32 atttypmod = PG_GETARG_INT32(2);
459+
Node *escontext = fcinfo->context;
460460
VarBit *result; /* The resulting bit string */
461461
char *sp; /* pointer into the character string */
462462
bits8 *r; /* pointer into the result */
@@ -494,7 +494,7 @@ varbit_in(PG_FUNCTION_ARGS)
494494
else
495495
{
496496
if (slen > VARBITMAXLEN / 4)
497-
ereport(ERROR,
497+
ereturn(escontext, (Datum) 0,
498498
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
499499
errmsg("bit string length exceeds the maximum allowed (%d)",
500500
VARBITMAXLEN)));
@@ -508,7 +508,7 @@ varbit_in(PG_FUNCTION_ARGS)
508508
if (atttypmod <= 0)
509509
atttypmod = bitlen;
510510
else if (bitlen > atttypmod)
511-
ereport(ERROR,
511+
ereturn(escontext, (Datum) 0,
512512
(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
513513
errmsg("bit string too long for type bit varying(%d)",
514514
atttypmod)));
@@ -530,7 +530,7 @@ varbit_in(PG_FUNCTION_ARGS)
530530
if (*sp == '1')
531531
*r |= x;
532532
else if (*sp != '0')
533-
ereport(ERROR,
533+
ereturn(escontext, (Datum) 0,
534534
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
535535
errmsg("\"%.*s\" is not a valid binary digit",
536536
pg_mblen(sp), sp)));
@@ -555,7 +555,7 @@ varbit_in(PG_FUNCTION_ARGS)
555555
else if (*sp >= 'a' && *sp <= 'f')
556556
x = (bits8) (*sp - 'a') + 10;
557557
else
558-
ereport(ERROR,
558+
ereturn(escontext, (Datum) 0,
559559
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
560560
errmsg("\"%.*s\" is not a valid hexadecimal digit",
561561
pg_mblen(sp), sp)));

0 commit comments

Comments
 (0)