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

Commit7a5f8b5

Browse files
committed
Improve coding of column-name parsing in psql's new crosstabview.c.
Coverity complained about this code, not without reason because it wasrather messy. Adjust it to not scribble on the passed string; that addsone malloc/free cycle per column name, which is going to be insignificantin context. We can actually const-ify both the string argument and thePGresult.Daniel Verité, with some further cleanup by me
1 parent2201d80 commit7a5f8b5

File tree

2 files changed

+40
-27
lines changed

2 files changed

+40
-27
lines changed

‎src/bin/psql/crosstabview.c

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -82,15 +82,16 @@ static bool printCrosstab(const PGresult *results,
8282
intnum_columns,pivot_field*piv_columns,intfield_for_columns,
8383
intnum_rows,pivot_field*piv_rows,intfield_for_rows,
8484
intfield_for_data);
85-
staticintparseColumnRefs(char*arg,PGresult*res,int**col_numbers,
85+
staticintparseColumnRefs(constchar*arg,constPGresult*res,
86+
int**col_numbers,
8687
intmax_columns,charseparator);
8788
staticvoidavlInit(avl_tree*tree);
8889
staticvoidavlMergeValue(avl_tree*tree,char*name,char*sort_value);
8990
staticintavlCollectFields(avl_tree*tree,avl_node*node,
9091
pivot_field*fields,intidx);
9192
staticvoidavlFree(avl_tree*tree,avl_node*node);
9293
staticvoidrankSort(intnum_columns,pivot_field*piv_columns);
93-
staticintindexOfColumn(constchar*arg,PGresult*res);
94+
staticintindexOfColumn(constchar*arg,constPGresult*res);
9495
staticintpivotFieldCompare(constvoid*a,constvoid*b);
9596
staticintrankCompare(constvoid*a,constvoid*b);
9697

@@ -103,7 +104,7 @@ static intrankCompare(const void *a, const void *b);
103104
* then call printCrosstab() for the actual output.
104105
*/
105106
bool
106-
PrintResultsInCrosstab(PGresult*res)
107+
PrintResultsInCrosstab(constPGresult*res)
107108
{
108109
char*opt_field_for_rows=pset.ctv_col_V;
109110
char*opt_field_for_columns=pset.ctv_col_H;
@@ -475,33 +476,37 @@ printCrosstab(const PGresult *results,
475476
}
476477

477478
/*
478-
* Parse col1[<sep>col2][<sep>col3]...
479-
* where colN can be:
479+
* Parse "arg", which is a string of column IDs separated by "separator".
480+
*
481+
* Each column ID can be:
480482
* - a number from 1 to PQnfields(res)
481483
* - an unquoted column name matching (case insensitively) one of PQfname(res,...)
482484
* - a quoted column name matching (case sensitively) one of PQfname(res,...)
483-
* max_columns: 0 if no maximum
485+
*
486+
* If max_columns > 0, it is the max number of column IDs allowed.
487+
*
488+
* On success, return number of column IDs found (possibly 0), and return a
489+
* malloc'd array of the matching column numbers of "res" into *col_numbers.
490+
*
491+
* On failure, return -1 and set *col_numbers to NULL.
484492
*/
485493
staticint
486-
parseColumnRefs(char*arg,
487-
PGresult*res,
494+
parseColumnRefs(constchar*arg,
495+
constPGresult*res,
488496
int**col_numbers,
489497
intmax_columns,
490498
charseparator)
491499
{
492-
char*p=arg;
500+
constchar*p=arg;
493501
charc;
494-
intcol_num=-1;
495-
intnb_cols=0;
496-
char*field_start=NULL;
502+
intnum_cols=0;
497503

498504
*col_numbers=NULL;
499505
while ((c=*p)!='\0')
500506
{
507+
constchar*field_start=p;
501508
boolquoted_field= false;
502509

503-
field_start=p;
504-
505510
/* first char */
506511
if (c=='"')
507512
{
@@ -533,20 +538,27 @@ parseColumnRefs(char *arg,
533538

534539
if (p!=field_start)
535540
{
536-
/* look up the column and add its index into *col_numbers */
537-
if (max_columns!=0&&nb_cols==max_columns)
541+
char*col_name;
542+
intcol_num;
543+
544+
/* enforce max_columns limit */
545+
if (max_columns>0&&num_cols==max_columns)
538546
{
539-
psql_error(_("No more than %d column references expected\n"),max_columns);
547+
psql_error(_("No more than %d column references expected\n"),
548+
max_columns);
540549
gotoerrfail;
541550
}
542-
c=*p;
543-
*p='\0';
544-
col_num=indexOfColumn(field_start,res);
551+
/* look up the column and add its index into *col_numbers */
552+
col_name=pg_malloc(p-field_start+1);
553+
memcpy(col_name,field_start,p-field_start);
554+
col_name[p-field_start]='\0';
555+
col_num=indexOfColumn(col_name,res);
556+
pg_free(col_name);
545557
if (col_num<0)
546558
gotoerrfail;
547-
*p=c;
548-
*col_numbers= (int*)pg_realloc(*col_numbers, (1+nb_cols)*sizeof(int));
549-
(*col_numbers)[nb_cols++]=col_num;
559+
*col_numbers=(int*)pg_realloc(*col_numbers,
560+
(num_cols+1)*sizeof(int));
561+
(*col_numbers)[num_cols++]=col_num;
550562
}
551563
else
552564
{
@@ -557,7 +569,7 @@ parseColumnRefs(char *arg,
557569
if (*p)
558570
p+=PQmblen(p,pset.encoding);
559571
}
560-
returnnb_cols;
572+
returnnum_cols;
561573

562574
errfail:
563575
pg_free(*col_numbers);
@@ -776,7 +788,7 @@ fieldNameEquals(const char *arg, const char *fieldname)
776788
charc;
777789

778790
if (*p++!='"')
779-
return!pg_strcasecmp(arg,fieldname);
791+
return(pg_strcasecmp(arg,fieldname)==0);
780792

781793
while ((c=*p++))
782794
{
@@ -805,7 +817,7 @@ fieldNameEquals(const char *arg, const char *fieldname)
805817
* or if it's ambiguous (arg corresponding to several columns)
806818
*/
807819
staticint
808-
indexOfColumn(constchar*arg,PGresult*res)
820+
indexOfColumn(constchar*arg,constPGresult*res)
809821
{
810822
intidx;
811823

‎src/bin/psql/crosstabview.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@
2222
#defineCROSSTABVIEW_MAX_COLUMNS 1600
2323

2424
/* prototypes */
25-
externboolPrintResultsInCrosstab(PGresult*res);
25+
externboolPrintResultsInCrosstab(constPGresult*res);
26+
2627
#endif/* CROSSTABVIEW_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp