3737#include "libpq-int.h"
3838
3939
40- static void do_field (const PQprintOpt * po ,const PGresult * res ,
40+ static bool do_field (const PQprintOpt * po ,const PGresult * res ,
4141const int i ,const int j ,const int fs_len ,
4242char * * fields ,
4343const int nFields ,const char * * fieldNames ,
@@ -80,12 +80,12 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
8080unsignedchar * fieldNotNum = NULL ;
8181char * border = NULL ;
8282char * * fields = NULL ;
83- const char * * fieldNames ;
83+ const char * * fieldNames = NULL ;
8484int fieldMaxLen = 0 ;
8585int numFieldName ;
8686int fs_len = strlen (po -> fieldSep );
8787int total_line_length = 0 ;
88- int usePipe = 0 ;
88+ bool usePipe = false ;
8989char * pagerenv ;
9090
9191#if defined(ENABLE_THREAD_SAFETY )&& !defined(WIN32 )
@@ -108,20 +108,13 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
108108#endif
109109
110110nTups = PQntuples (res );
111- if (!(fieldNames = (const char * * )calloc (nFields ,sizeof (char * ))))
111+ fieldNames = (const char * * )calloc (nFields ,sizeof (char * ));
112+ fieldNotNum = (unsignedchar * )calloc (nFields ,1 );
113+ fieldMax = (int * )calloc (nFields ,sizeof (int ));
114+ if (!fieldNames || !fieldNotNum || !fieldMax )
112115{
113116fprintf (stderr ,libpq_gettext ("out of memory\n" ));
114- abort ();
115- }
116- if (!(fieldNotNum = (unsignedchar * )calloc (nFields ,1 )))
117- {
118- fprintf (stderr ,libpq_gettext ("out of memory\n" ));
119- abort ();
120- }
121- if (!(fieldMax = (int * )calloc (nFields ,sizeof (int ))))
122- {
123- fprintf (stderr ,libpq_gettext ("out of memory\n" ));
124- abort ();
117+ gotoexit ;
125118}
126119for (numFieldName = 0 ;
127120po -> fieldName && po -> fieldName [numFieldName ];
@@ -190,7 +183,7 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
190183fout = popen (pagerenv ,"w" );
191184if (fout )
192185{
193- usePipe = 1 ;
186+ usePipe = true ;
194187#ifndef WIN32
195188#ifdef ENABLE_THREAD_SAFETY
196189if (pq_block_sigpipe (& osigset ,& sigpipe_pending )== 0 )
@@ -207,10 +200,12 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
207200
208201if (!po -> expanded && (po -> align || po -> html3 ))
209202{
210- if (!(fields = (char * * )calloc (nFields * (nTups + 1 ),sizeof (char * ))))
203+ fields = (char * * )calloc ((size_t )nTups + 1 ,
204+ nFields * sizeof (char * ));
205+ if (!fields )
211206{
212207fprintf (stderr ,libpq_gettext ("out of memory\n" ));
213- abort () ;
208+ goto exit ;
214209}
215210}
216211else if (po -> header && !po -> html3 )
@@ -264,9 +259,12 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
264259fprintf (fout ,libpq_gettext ("-- RECORD %d --\n" ),i );
265260}
266261for (j = 0 ;j < nFields ;j ++ )
267- do_field (po ,res ,i ,j ,fs_len ,fields ,nFields ,
268- fieldNames ,fieldNotNum ,
269- fieldMax ,fieldMaxLen ,fout );
262+ {
263+ if (!do_field (po ,res ,i ,j ,fs_len ,fields ,nFields ,
264+ fieldNames ,fieldNotNum ,
265+ fieldMax ,fieldMaxLen ,fout ))
266+ gotoexit ;
267+ }
270268if (po -> html3 && po -> expanded )
271269fputs ("</table>\n" ,fout );
272270}
@@ -297,18 +295,34 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
297295for (i = 0 ;i < nTups ;i ++ )
298296output_row (fout ,po ,nFields ,fields ,
299297fieldNotNum ,fieldMax ,border ,i );
300- free (fields );
301- if (border )
302- free (border );
303298}
304299if (po -> header && !po -> html3 )
305300fprintf (fout ,"(%d row%s)\n\n" ,PQntuples (res ),
306301(PQntuples (res )== 1 ) ?"" :"s" );
307302if (po -> html3 && !po -> expanded )
308303fputs ("</table>\n" ,fout );
309- free (fieldMax );
310- free (fieldNotNum );
311- free ((void * )fieldNames );
304+
305+ exit :
306+ if (fieldMax )
307+ free (fieldMax );
308+ if (fieldNotNum )
309+ free (fieldNotNum );
310+ if (border )
311+ free (border );
312+ if (fields )
313+ {
314+ /* if calloc succeeded, this shouldn't overflow size_t */
315+ size_t numfields = ((size_t )nTups + 1 )* (size_t )nFields ;
316+
317+ while (numfields -- > 0 )
318+ {
319+ if (fields [numfields ])
320+ free (fields [numfields ]);
321+ }
322+ free (fields );
323+ }
324+ if (fieldNames )
325+ free ((void * )fieldNames );
312326if (usePipe )
313327{
314328#ifdef WIN32
@@ -329,7 +343,7 @@ PQprint(FILE *fout, const PGresult *res, const PQprintOpt *po)
329343}
330344
331345
332- static void
346+ static bool
333347do_field (const PQprintOpt * po ,const PGresult * res ,
334348const int i ,const int j ,const int fs_len ,
335349char * * fields ,
@@ -397,7 +411,7 @@ do_field(const PQprintOpt *po, const PGresult *res,
397411if (!(fields [i * nFields + j ]= (char * )malloc (plen + 1 )))
398412{
399413fprintf (stderr ,libpq_gettext ("out of memory\n" ));
400- abort () ;
414+ return false ;
401415}
402416strcpy (fields [i * nFields + j ],pval );
403417}
@@ -440,6 +454,7 @@ do_field(const PQprintOpt *po, const PGresult *res,
440454}
441455}
442456}
457+ return true;
443458}
444459
445460
@@ -467,7 +482,7 @@ do_header(FILE *fout, const PQprintOpt *po, const int nFields, int *fieldMax,
467482if (!border )
468483{
469484fprintf (stderr ,libpq_gettext ("out of memory\n" ));
470- abort () ;
485+ return NULL ;
471486}
472487p = border ;
473488if (po -> standard )
@@ -558,8 +573,6 @@ output_row(FILE *fout, const PQprintOpt *po, const int nFields, char **fields,
558573if (po -> standard || field_index + 1 < nFields )
559574fputs (po -> fieldSep ,fout );
560575}
561- if (p )
562- free (p );
563576}
564577if (po -> html3 )
565578fputs ("</tr>" ,fout );
@@ -609,7 +622,7 @@ PQdisplayTuples(const PGresult *res,
609622if (!fLength )
610623{
611624fprintf (stderr ,libpq_gettext ("out of memory\n" ));
612- abort () ;
625+ return ;
613626}
614627
615628for (j = 0 ;j < nFields ;j ++ )
@@ -707,7 +720,7 @@ PQprintTuples(const PGresult *res,
707720if (!tborder )
708721{
709722fprintf (stderr ,libpq_gettext ("out of memory\n" ));
710- abort () ;
723+ return ;
711724}
712725for (i = 0 ;i < width ;i ++ )
713726tborder [i ]= '-' ;