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

Commitf900af7

Browse files
committed
Further tightening of the array literal parser. Prevent junk
from being accepted after the outer right brace. Per report fromMarkus Bertheau.Also add regression test cases for this change, and for previousrecent array literal parser changes.
1 parentf444daf commitf900af7

File tree

3 files changed

+107
-6
lines changed

3 files changed

+107
-6
lines changed

‎src/backend/utils/adt/arrayfuncs.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.107 2004/08/08 05:01:55 joe Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.108 2004/08/28 19:31:28 joe Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -183,9 +183,7 @@ array_in(PG_FUNCTION_ARGS)
183183
typioparam=my_extra->typioparam;
184184

185185
/* Make a modifiable copy of the input */
186-
/* XXX why are we allocating an extra 2 bytes here? */
187-
string_save= (char*)palloc(strlen(string)+3);
188-
strcpy(string_save,string);
186+
string_save=pstrdup(string);
189187

190188
/*
191189
* If the input string starts with dimension info, read and use that.
@@ -375,6 +373,7 @@ ArrayCount(char *str, int *dim, char typdelim)
375373
nelems_last[MAXDIM];
376374
boolscanning_string= false;
377375
booleoArray= false;
376+
boolempty_array= true;
378377
char*ptr;
379378
ArrayParseStateparse_state=ARRAY_NO_LEVEL;
380379

@@ -385,7 +384,7 @@ ArrayCount(char *str, int *dim, char typdelim)
385384
}
386385

387386
/* special case for an empty array */
388-
if (strncmp(str,"{}",2)==0)
387+
if (strcmp(str,"{}")==0)
389388
return0;
390389

391390
ptr=str;
@@ -395,6 +394,10 @@ ArrayCount(char *str, int *dim, char typdelim)
395394

396395
while (!itemdone)
397396
{
397+
if (parse_state==ARRAY_ELEM_STARTED||
398+
parse_state==ARRAY_QUOTED_ELEM_STARTED)
399+
empty_array= false;
400+
398401
switch (*ptr)
399402
{
400403
case'\0':
@@ -481,7 +484,8 @@ ArrayCount(char *str, int *dim, char typdelim)
481484
if (parse_state!=ARRAY_ELEM_STARTED&&
482485
parse_state!=ARRAY_ELEM_COMPLETED&&
483486
parse_state!=ARRAY_QUOTED_ELEM_COMPLETED&&
484-
parse_state!=ARRAY_LEVEL_COMPLETED)
487+
parse_state!=ARRAY_LEVEL_COMPLETED&&
488+
!(nest_level==1&&parse_state==ARRAY_LEVEL_STARTED))
485489
ereport(ERROR,
486490
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
487491
errmsg("malformed array literal: \"%s\"",str)));
@@ -562,6 +566,20 @@ ArrayCount(char *str, int *dim, char typdelim)
562566
temp[ndim-1]++;
563567
ptr++;
564568
}
569+
570+
/* only whitespace is allowed after the closing brace */
571+
while (*ptr)
572+
{
573+
if (!isspace(*ptr++))
574+
ereport(ERROR,
575+
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
576+
errmsg("malformed array literal: \"%s\"",str)));
577+
}
578+
579+
/* special case for an empty array */
580+
if (empty_array)
581+
return0;
582+
565583
for (i=0;i<ndim;++i)
566584
dim[i]=temp[i];
567585

‎src/test/regress/expected/arrays.out

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -425,3 +425,61 @@ select 'foo' ilike all (array['F%', '%O']); -- t
425425
t
426426
(1 row)
427427

428+
--
429+
-- General array parser tests
430+
--
431+
-- none of the following should be accepted
432+
select '{{1,{2}},{2,3}}'::text[];
433+
ERROR: malformed array literal: "{{1,{2}},{2,3}}"
434+
select '{{},{}}'::text[];
435+
ERROR: malformed array literal: "{{},{}}"
436+
select '{{1,2},\\{2,3}}'::text[];
437+
ERROR: malformed array literal: "{{1,2},\{2,3}}"
438+
select '{{"1 2" x},{3}}'::text[];
439+
ERROR: malformed array literal: "{{"1 2" x},{3}}"
440+
select '{}}'::text[];
441+
ERROR: malformed array literal: "{}}"
442+
select '{ }}'::text[];
443+
ERROR: malformed array literal: "{ }}"
444+
-- none of the above should be accepted
445+
-- all of the following should be accepted
446+
select '{}'::text[];
447+
text
448+
------
449+
{}
450+
(1 row)
451+
452+
select '{{{1,2,3,4},{2,3,4,5}},{{3,4,5,6},{4,5,6,7}}}'::text[];
453+
text
454+
-----------------------------------------------
455+
{{{1,2,3,4},{2,3,4,5}},{{3,4,5,6},{4,5,6,7}}}
456+
(1 row)
457+
458+
select '{0 second ,0 second}'::interval[];
459+
interval
460+
---------------
461+
{"@ 0","@ 0"}
462+
(1 row)
463+
464+
select '{ { "," } , { 3 } }'::text[];
465+
text
466+
-------------
467+
{{","},{3}}
468+
(1 row)
469+
470+
select ' { { " 0 second " , 0 second } }'::text[];
471+
text
472+
-------------------------------
473+
{{" 0 second ","0 second"}}
474+
(1 row)
475+
476+
select '{
477+
0 second,
478+
@ 1 hour @ 42 minutes @ 20 seconds
479+
}'::interval[];
480+
interval
481+
------------------------------------
482+
{"@ 0","@ 1 hour 42 mins 20 secs"}
483+
(1 row)
484+
485+
-- all of the above should be accepted

‎src/test/regress/sql/arrays.sql

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,3 +192,28 @@ select 'foo' not like any (array['%a', '%b']); -- t
192192
select'foo' notlike all (array['%a','%o']);-- f
193193
select'foo' ilike any (array['%A','%O']);-- t
194194
select'foo' ilike all (array['F%','%O']);-- t
195+
196+
--
197+
-- General array parser tests
198+
--
199+
200+
-- none of the following should be accepted
201+
select'{{1,{2}},{2,3}}'::text[];
202+
select'{{},{}}'::text[];
203+
select'{{1,2},\\{2,3}}'::text[];
204+
select'{{"1 2" x},{3}}'::text[];
205+
select'{}}'::text[];
206+
select'{ }}'::text[];
207+
-- none of the above should be accepted
208+
209+
-- all of the following should be accepted
210+
select'{}'::text[];
211+
select'{{{1,2,3,4},{2,3,4,5}},{{3,4,5,6},{4,5,6,7}}}'::text[];
212+
select'{0 second ,0 second}'::interval[];
213+
select'{ { "," } , { 3 } }'::text[];
214+
select' { { " 0 second " , 0 second } }'::text[];
215+
select'{
216+
0 second,
217+
@ 1 hour @ 42 minutes @ 20 seconds
218+
}'::interval[];
219+
-- all of the above should be accepted

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp