Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit197f98a

Browse files
committed
Convert hstore_in to report errors softly.
The error reporting here was not only old and crufty, but untested.I took the opportunity to bring the messages into some sort ofcompliance with our message style guidelines.Discussion:https://postgr.es/m/6B6A5C77-60AD-4A71-9F3A-B2C026A281A6@dunslane.net
1 parenta5434c5 commit197f98a

File tree

3 files changed

+133
-28
lines changed

3 files changed

+133
-28
lines changed

‎contrib/hstore/expected/hstore.out

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,40 @@ select ''::hstore;
243243

244244
(1 row)
245245

246+
-- invalid input
247+
select ' =>null'::hstore;
248+
ERROR: syntax error in hstore, near "=" at position 2
249+
LINE 1: select ' =>null'::hstore;
250+
^
251+
select 'aa=>"'::hstore;
252+
ERROR: syntax error in hstore: unexpected end of string
253+
LINE 1: select 'aa=>"'::hstore;
254+
^
255+
-- also try it with non-error-throwing API
256+
select pg_input_is_valid('a=>b', 'hstore');
257+
pg_input_is_valid
258+
-------------------
259+
t
260+
(1 row)
261+
262+
select pg_input_is_valid('a=b', 'hstore');
263+
pg_input_is_valid
264+
-------------------
265+
f
266+
(1 row)
267+
268+
select pg_input_error_message('a=b', 'hstore');
269+
pg_input_error_message
270+
------------------------------------------------
271+
syntax error in hstore, near "b" at position 2
272+
(1 row)
273+
274+
select pg_input_error_message(' =>b', 'hstore');
275+
pg_input_error_message
276+
------------------------------------------------
277+
syntax error in hstore, near "=" at position 1
278+
(1 row)
279+
246280
-- -> operator
247281
select 'aa=>b, c=>d , b=>16'::hstore->'c';
248282
?column?

‎contrib/hstore/hstore_io.c

Lines changed: 88 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include"hstore.h"
1313
#include"lib/stringinfo.h"
1414
#include"libpq/pqformat.h"
15+
#include"nodes/miscnodes.h"
1516
#include"utils/builtins.h"
1617
#include"utils/json.h"
1718
#include"utils/jsonb.h"
@@ -32,12 +33,17 @@ typedef struct
3233
char*cur;
3334
char*word;
3435
intwordlen;
36+
Node*escontext;
3537

3638
Pairs*pairs;
3739
intpcur;
3840
intplen;
3941
}HSParser;
4042

43+
staticboolhstoreCheckKeyLength(size_tlen,HSParser*state);
44+
staticboolhstoreCheckValLength(size_tlen,HSParser*state);
45+
46+
4147
#defineRESIZEPRSBUF \
4248
do { \
4349
if ( state->cur - state->word + 1 >= state->wordlen ) \
@@ -49,6 +55,32 @@ do { \
4955
} \
5056
} while (0)
5157

58+
#definePRSSYNTAXERROR return prssyntaxerror(state)
59+
60+
staticbool
61+
prssyntaxerror(HSParser*state)
62+
{
63+
errsave(state->escontext,
64+
(errcode(ERRCODE_SYNTAX_ERROR),
65+
errmsg("syntax error in hstore, near \"%.*s\" at position %d",
66+
pg_mblen(state->ptr),state->ptr,
67+
(int) (state->ptr-state->begin))));
68+
/* In soft error situation, return false as convenience for caller */
69+
return false;
70+
}
71+
72+
#definePRSEOF return prseof(state)
73+
74+
staticbool
75+
prseof(HSParser*state)
76+
{
77+
errsave(state->escontext,
78+
(errcode(ERRCODE_SYNTAX_ERROR),
79+
errmsg("syntax error in hstore: unexpected end of string")));
80+
/* In soft error situation, return false as convenience for caller */
81+
return false;
82+
}
83+
5284

5385
#defineGV_WAITVAL 0
5486
#defineGV_INVAL 1
@@ -80,9 +112,7 @@ get_val(HSParser *state, bool ignoreeq, bool *escaped)
80112
}
81113
elseif (*(state->ptr)=='='&& !ignoreeq)
82114
{
83-
elog(ERROR,"Syntax error near \"%.*s\" at position %d",
84-
pg_mblen(state->ptr),state->ptr,
85-
(int32) (state->ptr-state->begin));
115+
PRSSYNTAXERROR;
86116
}
87117
elseif (*(state->ptr)=='\\')
88118
{
@@ -139,7 +169,7 @@ get_val(HSParser *state, bool ignoreeq, bool *escaped)
139169
}
140170
elseif (*(state->ptr)=='\0')
141171
{
142-
elog(ERROR,"Unexpected end of string");
172+
PRSEOF;
143173
}
144174
else
145175
{
@@ -151,7 +181,7 @@ get_val(HSParser *state, bool ignoreeq, bool *escaped)
151181
elseif (st==GV_WAITESCIN)
152182
{
153183
if (*(state->ptr)=='\0')
154-
elog(ERROR,"Unexpected end of string");
184+
PRSEOF;
155185
RESIZEPRSBUF;
156186
*(state->cur)=*(state->ptr);
157187
state->cur++;
@@ -160,14 +190,14 @@ get_val(HSParser *state, bool ignoreeq, bool *escaped)
160190
elseif (st==GV_WAITESCESCIN)
161191
{
162192
if (*(state->ptr)=='\0')
163-
elog(ERROR,"Unexpected end of string");
193+
PRSEOF;
164194
RESIZEPRSBUF;
165195
*(state->cur)=*(state->ptr);
166196
state->cur++;
167197
st=GV_INESCVAL;
168198
}
169199
else
170-
elog(ERROR,"Unknownstate %d at position line %d in file '%s'",st,__LINE__,__FILE__);
200+
elog(ERROR,"unrecognized get_valstate: %d",st);
171201

172202
state->ptr++;
173203
}
@@ -180,7 +210,7 @@ get_val(HSParser *state, bool ignoreeq, bool *escaped)
180210
#defineWDEL4
181211

182212

183-
staticvoid
213+
staticbool
184214
parse_hstore(HSParser*state)
185215
{
186216
intst=WKEY;
@@ -197,14 +227,20 @@ parse_hstore(HSParser *state)
197227
if (st==WKEY)
198228
{
199229
if (!get_val(state, false,&escaped))
200-
return;
230+
{
231+
if (SOFT_ERROR_OCCURRED(state->escontext))
232+
return false;
233+
return true;/* EOF, all okay */
234+
}
201235
if (state->pcur >=state->plen)
202236
{
203237
state->plen *=2;
204238
state->pairs= (Pairs*)repalloc(state->pairs,sizeof(Pairs)*state->plen);
205239
}
240+
if (!hstoreCheckKeyLength(state->cur-state->word,state))
241+
return false;
206242
state->pairs[state->pcur].key=state->word;
207-
state->pairs[state->pcur].keylen=hstoreCheckKeyLen(state->cur-state->word);
243+
state->pairs[state->pcur].keylen=state->cur-state->word;
208244
state->pairs[state->pcur].val=NULL;
209245
state->word=NULL;
210246
st=WEQ;
@@ -217,13 +253,11 @@ parse_hstore(HSParser *state)
217253
}
218254
elseif (*(state->ptr)=='\0')
219255
{
220-
elog(ERROR,"Unexpected end of string");
256+
PRSEOF;
221257
}
222258
elseif (!isspace((unsignedchar)*(state->ptr)))
223259
{
224-
elog(ERROR,"Syntax error near \"%.*s\" at position %d",
225-
pg_mblen(state->ptr),state->ptr,
226-
(int32) (state->ptr-state->begin));
260+
PRSSYNTAXERROR;
227261
}
228262
}
229263
elseif (st==WGT)
@@ -234,27 +268,31 @@ parse_hstore(HSParser *state)
234268
}
235269
elseif (*(state->ptr)=='\0')
236270
{
237-
elog(ERROR,"Unexpected end of string");
271+
PRSEOF;
238272
}
239273
else
240274
{
241-
elog(ERROR,"Syntax error near \"%.*s\" at position %d",
242-
pg_mblen(state->ptr),state->ptr,
243-
(int32) (state->ptr-state->begin));
275+
PRSSYNTAXERROR;
244276
}
245277
}
246278
elseif (st==WVAL)
247279
{
248280
if (!get_val(state, true,&escaped))
249-
elog(ERROR,"Unexpected end of string");
281+
{
282+
if (SOFT_ERROR_OCCURRED(state->escontext))
283+
return false;
284+
PRSEOF;
285+
}
286+
if (!hstoreCheckValLength(state->cur-state->word,state))
287+
return false;
250288
state->pairs[state->pcur].val=state->word;
251-
state->pairs[state->pcur].vallen=hstoreCheckValLen(state->cur-state->word);
289+
state->pairs[state->pcur].vallen=state->cur-state->word;
252290
state->pairs[state->pcur].isnull= false;
253291
state->pairs[state->pcur].needfree= true;
254292
if (state->cur-state->word==4&& !escaped)
255293
{
256294
state->word[4]='\0';
257-
if (0==pg_strcasecmp(state->word,"null"))
295+
if (pg_strcasecmp(state->word,"null")==0)
258296
state->pairs[state->pcur].isnull= true;
259297
}
260298
state->word=NULL;
@@ -269,17 +307,15 @@ parse_hstore(HSParser *state)
269307
}
270308
elseif (*(state->ptr)=='\0')
271309
{
272-
return;
310+
return true;
273311
}
274312
elseif (!isspace((unsignedchar)*(state->ptr)))
275313
{
276-
elog(ERROR,"Syntax error near \"%.*s\" at position %d",
277-
pg_mblen(state->ptr),state->ptr,
278-
(int32) (state->ptr-state->begin));
314+
PRSSYNTAXERROR;
279315
}
280316
}
281317
else
282-
elog(ERROR,"Unknownstate %d at line %d in file '%s'",st,__LINE__,__FILE__);
318+
elog(ERROR,"unrecognized parse_hstorestate: %d",st);
283319

284320
state->ptr++;
285321
}
@@ -373,6 +409,16 @@ hstoreCheckKeyLen(size_t len)
373409
returnlen;
374410
}
375411

412+
staticbool
413+
hstoreCheckKeyLength(size_tlen,HSParser*state)
414+
{
415+
if (len>HSTORE_MAX_KEY_LEN)
416+
ereturn(state->escontext, false,
417+
(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
418+
errmsg("string too long for hstore key")));
419+
return true;
420+
}
421+
376422
size_t
377423
hstoreCheckValLen(size_tlen)
378424
{
@@ -383,6 +429,16 @@ hstoreCheckValLen(size_t len)
383429
returnlen;
384430
}
385431

432+
staticbool
433+
hstoreCheckValLength(size_tlen,HSParser*state)
434+
{
435+
if (len>HSTORE_MAX_VALUE_LEN)
436+
ereturn(state->escontext, false,
437+
(errcode(ERRCODE_STRING_DATA_RIGHT_TRUNCATION),
438+
errmsg("string too long for hstore value")));
439+
return true;
440+
}
441+
386442

387443
HStore*
388444
hstorePairs(Pairs*pairs,int32pcount,int32buflen)
@@ -418,13 +474,17 @@ PG_FUNCTION_INFO_V1(hstore_in);
418474
Datum
419475
hstore_in(PG_FUNCTION_ARGS)
420476
{
477+
char*str=PG_GETARG_CSTRING(0);
478+
Node*escontext=fcinfo->context;
421479
HSParserstate;
422480
int32buflen;
423481
HStore*out;
424482

425-
state.begin=PG_GETARG_CSTRING(0);
483+
state.begin=str;
484+
state.escontext=escontext;
426485

427-
parse_hstore(&state);
486+
if (!parse_hstore(&state))
487+
PG_RETURN_NULL();
428488

429489
state.pcur=hstoreUniquePairs(state.pairs,state.pcur,&buflen);
430490

‎contrib/hstore/sql/hstore.sql

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,17 @@ select e'\\"a=>q"w'::hstore;
5353
select''::hstore;
5454
select''::hstore;
5555

56+
-- invalid input
57+
select' =>null'::hstore;
58+
select'aa=>"'::hstore;
59+
60+
-- also try it with non-error-throwing API
61+
select pg_input_is_valid('a=>b','hstore');
62+
select pg_input_is_valid('a=b','hstore');
63+
select pg_input_error_message('a=b','hstore');
64+
select pg_input_error_message(' =>b','hstore');
65+
66+
5667
-- -> operator
5768

5869
select'aa=>b, c=>d , b=>16'::hstore->'c';

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp