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

Commitf1f5978

Browse files
committed
Fix possible buffer overrun in \d command: substr(..., 128) produces
a result of at most 128 chars, but that could be more than 128 bytes.Also ensure we don't try to pfree uninitialized pointers during errorcleanup.
1 parente2ad581 commitf1f5978

File tree

1 file changed

+41
-24
lines changed

1 file changed

+41
-24
lines changed

‎src/bin/psql/describe.c

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*
44
* Copyright 2000-2002 by PostgreSQL Global Development Group
55
*
6-
* $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.72 2002/12/12 21:02:24 momjian Exp $
6+
* $Header: /cvsroot/pgsql/src/bin/psql/describe.c,v 1.73 2002/12/21 01:07:07 tgl Exp $
77
*/
88
#include"postgres_fe.h"
99
#include"describe.h"
@@ -44,6 +44,16 @@ xmalloc(size_t size)
4444
returntmp;
4545
}
4646

47+
staticvoid*
48+
xmalloczero(size_tsize)
49+
{
50+
void*tmp;
51+
52+
tmp=xmalloc(size);
53+
memset(tmp,0,size);
54+
returntmp;
55+
}
56+
4757

4858
/*----------------
4959
* Handlers for various slash commands displaying some sort of list
@@ -635,7 +645,9 @@ describeOneTableDetails(const char *schemaname,
635645
char**footers=NULL;
636646
char**ptr;
637647
PQExpBufferDatatitle;
638-
unsignedintcols=0;
648+
PQExpBufferDatatmpbuf;
649+
intcols=0;
650+
intnumrows=0;
639651
struct
640652
{
641653
boolhasindex;
@@ -644,12 +656,14 @@ describeOneTableDetails(const char *schemaname,
644656
int16triggers;
645657
boolhasrules;
646658
}tableinfo;
659+
boolshow_modifiers= false;
647660
boolretval;
648661

649662
retval= false;
650663

651664
initPQExpBuffer(&buf);
652665
initPQExpBuffer(&title);
666+
initPQExpBuffer(&tmpbuf);
653667

654668
/* Get general table info */
655669
printfPQExpBuffer(&buf,
@@ -683,6 +697,7 @@ describeOneTableDetails(const char *schemaname,
683697

684698
if (tableinfo.relkind=='r'||tableinfo.relkind=='v')
685699
{
700+
show_modifiers= true;
686701
cols++;
687702
headers[cols-1]=_("Modifiers");
688703
}
@@ -715,6 +730,7 @@ describeOneTableDetails(const char *schemaname,
715730
res=PSQLexec(buf.data, false);
716731
if (!res)
717732
gotoerror_return;
733+
numrows=PQntuples(res);
718734

719735
/* Check if table is a view */
720736
if (tableinfo.relkind=='v')
@@ -733,10 +749,10 @@ describeOneTableDetails(const char *schemaname,
733749
}
734750

735751
/* Generate table cells to be printed */
736-
cells=xmalloc((PQntuples(res)*cols+1)*sizeof(*cells));
737-
cells[PQntuples(res)*cols]=NULL;/* end of list */
752+
/* note: initialize allcells[] to NULL in case of error exit */
753+
cells=xmalloczero((numrows*cols+1)*sizeof(*cells));
738754

739-
for (i=0;i<PQntuples(res);i++)
755+
for (i=0;i<numrows;i++)
740756
{
741757
/* Name */
742758
cells[i*cols+0]=PQgetvalue(res,i,0);/* don't free this
@@ -747,12 +763,11 @@ describeOneTableDetails(const char *schemaname,
747763

748764
/* Extra: not null and default */
749765
/* (I'm cutting off the 'default' string at 128) */
750-
if (tableinfo.relkind=='r'||tableinfo.relkind=='v')
766+
if (show_modifiers)
751767
{
752-
cells[i*cols+2]=xmalloc(128+128);
753-
cells[i*cols+2][0]='\0';
768+
resetPQExpBuffer(&tmpbuf);
754769
if (strcmp(PQgetvalue(res,i,2),"t")==0)
755-
strcat(cells[i*cols+2],"not null");
770+
appendPQExpBufferStr(&tmpbuf,"not null");
756771

757772
/* handle "default" here */
758773
if (strcmp(PQgetvalue(res,i,3),"t")==0)
@@ -761,18 +776,21 @@ describeOneTableDetails(const char *schemaname,
761776

762777
printfPQExpBuffer(&buf,
763778
"SELECT substring(d.adsrc for 128) FROM pg_catalog.pg_attrdef d\n"
764-
"WHERE d.adrelid = '%s' AND d.adnum = %s",
779+
"WHERE d.adrelid = '%s' AND d.adnum = %s",
765780
oid,PQgetvalue(res,i,4));
766781

767782
result=PSQLexec(buf.data, false);
768783

769-
if (cells[i*cols+2][0])
770-
strcat(cells[i*cols+2]," ");
771-
strcat(cells[i*cols+2],"default ");
772-
strcat(cells[i*cols+2],result ?PQgetvalue(result,0,0) :"?");
784+
if (tmpbuf.len>0)
785+
appendPQExpBufferStr(&tmpbuf," ");
786+
787+
appendPQExpBuffer(&tmpbuf,"default %s",
788+
result ?PQgetvalue(result,0,0) :"?");
773789

774790
PQclear(result);
775791
}
792+
793+
cells[i*cols+2]=xstrdup(tmpbuf.data);
776794
}
777795

778796
/* Description */
@@ -841,15 +859,12 @@ describeOneTableDetails(const char *schemaname,
841859
}
842860
else
843861
{
844-
PQExpBufferDatatmpbuf;
845862
char*indisunique=PQgetvalue(result,0,0);
846863
char*indisprimary=PQgetvalue(result,0,1);
847864
char*indamname=PQgetvalue(result,0,2);
848865
char*indtable=PQgetvalue(result,0,3);
849866
char*indpred=PQgetvalue(result,0,4);
850867

851-
initPQExpBuffer(&tmpbuf);
852-
853868
if (strcmp(indisprimary,"t")==0)
854869
printfPQExpBuffer(&tmpbuf,_("primary key, "));
855870
elseif (strcmp(indisunique,"t")==0)
@@ -865,10 +880,9 @@ describeOneTableDetails(const char *schemaname,
865880
if (strlen(indpred))
866881
appendPQExpBuffer(&tmpbuf,", predicate %s",indpred);
867882

868-
footers=xmalloc(2*sizeof(*footers));
883+
footers=xmalloczero(2*sizeof(*footers));
869884
footers[0]=xstrdup(tmpbuf.data);
870885
footers[1]=NULL;
871-
termPQExpBuffer(&tmpbuf);
872886
}
873887

874888
PQclear(result);
@@ -895,7 +909,7 @@ describeOneTableDetails(const char *schemaname,
895909
}
896910

897911
/* Footer information about a view */
898-
footers=xmalloc((rule_count+2)*sizeof(*footers));
912+
footers=xmalloczero((rule_count+2)*sizeof(*footers));
899913
footers[count_footers]=xmalloc(64+strlen(view_def));
900914
snprintf(footers[count_footers],64+strlen(view_def),
901915
_("View definition: %s"),view_def);
@@ -1018,8 +1032,8 @@ describeOneTableDetails(const char *schemaname,
10181032
foreignkey_count=PQntuples(result5);
10191033
}
10201034

1021-
footers=xmalloc((index_count+check_count+rule_count+trigger_count+foreignkey_count+1)
1022-
*sizeof(*footers));
1035+
footers=xmalloczero((index_count+check_count+rule_count+trigger_count+foreignkey_count+1)
1036+
*sizeof(*footers));
10231037

10241038
/* print indexes */
10251039
for (i=0;i<index_count;i++)
@@ -1148,12 +1162,15 @@ describeOneTableDetails(const char *schemaname,
11481162
/* clean up */
11491163
termPQExpBuffer(&buf);
11501164
termPQExpBuffer(&title);
1165+
termPQExpBuffer(&tmpbuf);
11511166

11521167
if (cells)
11531168
{
1154-
for (i=0;i<PQntuples(res);i++)
1155-
if (tableinfo.relkind=='r'||tableinfo.relkind=='v')
1169+
for (i=0;i<numrows;i++)
1170+
{
1171+
if (show_modifiers)
11561172
free(cells[i*cols+2]);
1173+
}
11571174
free(cells);
11581175
}
11591176

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp