Skip to content

Commit d128852

Browse files
committed
In the Programmer's Guide, the sample code for accessing large objects
from libpq has two functions with memory leaks. The functions pickout() and overwrite() malloc space for buf which is never freed. See http://www.postgresql.org/users-lounge/docs/7.0/programmer/largeobjects3207.htm This problem is also in the 6.5 docs at http://www.postgresql.org/users-lounge/docs/6.5/programmer/x3184.htm Nishad Prakash
1 parent a7ea9f4 commit d128852

File tree

1 file changed

+118
-97
lines changed

1 file changed

+118
-97
lines changed

doc/src/sgml/lobj.sgml

Lines changed: 118 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.14 2000/12/21 22:55:27 petere Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/lobj.sgml,v 1.15 2001/01/20 00:05:54 momjian Exp $
33
-->
44

55
<chapter id="largeObjects">
@@ -316,48 +316,52 @@ SELECT lo_export(image.raster, '/tmp/motd') from image
316316
*--------------------------------------------------------------
317317
*/
318318
#include &lt;stdio.h&gt;
319-
#include "libpq-fe.h"
320-
#include "libpq/libpq-fs.h"
319+
#include &quot;libpq-fe.h&quot;
320+
#include &quot;libpq/libpq-fs.h&quot;
321321

322322
#define BUFSIZE 1024
323323

324324
/*
325-
* importFile * import file "in_filename" into database as large object "lobjOid"
325+
* importFile * import file &quot;in_filename&quot; into database as large object &quot;lob
326+
jOid&quot;
326327
*
327328
*/
328-
Oid importFile(PGconn *conn, char *filename)
329+
Oid
330+
importFile(PGconn *conn, char *filename)
329331
{
330-
Oid lobjId;
331-
int lobj_fd;
332-
char buf[BUFSIZE];
333-
int nbytes, tmp;
334-
int fd;
332+
Oid lobjId;
333+
int lobj_fd;
334+
char buf[BUFSIZE];
335+
int nbytes,
336+
tmp;
337+
int fd;
335338

336339
/*
337340
* open the file to be read in
338341
*/
339342
fd = open(filename, O_RDONLY, 0666);
340-
if (fd &lt; 0) { /* error */
341-
fprintf(stderr, "can't open unix file %s\n", filename);
343+
if (fd &lt; 0)
344+
{ /* error */
345+
fprintf(stderr, &quot;can't open unix file %s\n&quot;, filename);
342346
}
343347

344348
/*
345349
* create the large object
346350
*/
347-
lobjId = lo_creat(conn, INV_READ|INV_WRITE);
348-
if (lobjId == 0) {
349-
fprintf(stderr, "can't create large object\n");
350-
}
351+
lobjId = lo_creat(conn, INV_READ | INV_WRITE);
352+
if (lobjId == 0)
353+
fprintf(stderr, &quot;can't create large object\n&quot;);
351354

352355
lobj_fd = lo_open(conn, lobjId, INV_WRITE);
356+
353357
/*
354358
* read in from the Unix file and write to the inversion file
355359
*/
356-
while ((nbytes = read(fd, buf, BUFSIZE)) &gt; 0) {
357-
tmp = lo_write(conn, lobj_fd, buf, nbytes);
358-
if (tmp &lt; nbytes) {
359-
fprintf(stderr, "error while reading large object\n");
360-
}
360+
while ((nbytes = read(fd, buf, BUFSIZE)) &gt; 0)
361+
{
362+
tmp = lo_write(conn, lobj_fd, buf, nbytes);
363+
if (tmp &lt; nbytes)
364+
fprintf(stderr, &quot;error while reading large object\n&quot;);
361365
}
362366

363367
(void) close(fd);
@@ -366,101 +370,115 @@ Oid importFile(PGconn *conn, char *filename)
366370
return lobjId;
367371
}
368372

369-
void pickout(PGconn *conn, Oid lobjId, int start, int len)
373+
void
374+
pickout(PGconn *conn, Oid lobjId, int start, int len)
370375
{
371-
int lobj_fd;
372-
char* buf;
373-
int nbytes;
374-
int nread;
376+
int lobj_fd;
377+
char *buf;
378+
int nbytes;
379+
int nread;
375380

376381
lobj_fd = lo_open(conn, lobjId, INV_READ);
377-
if (lobj_fd &lt; 0) {
378-
fprintf(stderr,"can't open large object %d\n",
379-
lobjId);
382+
if (lobj_fd &lt; 0)
383+
{
384+
fprintf(stderr, &quot;can't open large object %d\n&quot;,
385+
lobjId);
380386
}
381387

382388
lo_lseek(conn, lobj_fd, start, SEEK_SET);
383-
buf = malloc(len+1);
389+
buf = malloc(len + 1);
384390

385391
nread = 0;
386-
while (len - nread &gt; 0) {
387-
nbytes = lo_read(conn, lobj_fd, buf, len - nread);
388-
buf[nbytes] = ' ';
389-
fprintf(stderr,"&gt;&gt;&gt; %s", buf);
390-
nread += nbytes;
392+
while (len - nread &gt; 0)
393+
{
394+
nbytes = lo_read(conn, lobj_fd, buf, len - nread);
395+
buf[nbytes] = ' ';
396+
fprintf(stderr, &quot;&gt;&gt;&gt; %s&quot;, buf);
397+
nread += nbytes;
391398
}
392-
fprintf(stderr,"\n");
399+
free(buf);
400+
fprintf(stderr, &quot;\n&quot;);
393401
lo_close(conn, lobj_fd);
394402
}
395403

396-
void overwrite(PGconn *conn, Oid lobjId, int start, int len)
404+
void
405+
overwrite(PGconn *conn, Oid lobjId, int start, int len)
397406
{
398-
int lobj_fd;
399-
char* buf;
400-
int nbytes;
401-
int nwritten;
402-
int i;
407+
int lobj_fd;
408+
char *buf;
409+
int nbytes;
410+
int nwritten;
411+
int i;
403412

404413
lobj_fd = lo_open(conn, lobjId, INV_READ);
405-
if (lobj_fd &lt; 0) {
406-
fprintf(stderr,"can't open large object %d\n",
407-
lobjId);
414+
if (lobj_fd &lt; 0)
415+
{
416+
fprintf(stderr, &quot;can't open large object %d\n&quot;,
417+
lobjId);
408418
}
409419

410420
lo_lseek(conn, lobj_fd, start, SEEK_SET);
411-
buf = malloc(len+1);
421+
buf = malloc(len + 1);
412422

413-
for (i=0;i&lt;len;i++)
414-
buf[i] = 'X';
423+
for (i = 0; i &lt; len; i++)
424+
buf[i] = 'X';
415425
buf[i] = ' ';
416426

417427
nwritten = 0;
418-
while (len - nwritten &gt; 0) {
419-
nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
420-
nwritten += nbytes;
428+
while (len - nwritten &gt; 0)
429+
{
430+
nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
431+
nwritten += nbytes;
421432
}
422-
fprintf(stderr,"\n");
433+
free(buf);
434+
fprintf(stderr, &quot;\n&quot;);
423435
lo_close(conn, lobj_fd);
424436
}
425437

426438
/*
427-
* exportFile * export large object "lobjOid" to file "out_filename"
439+
* exportFile * export large object &quot;lobjOid&quot; to file &quot;out_filename&quot;
428440
*
429441
*/
430-
void exportFile(PGconn *conn, Oid lobjId, char *filename)
442+
void
443+
exportFile(PGconn *conn, Oid lobjId, char *filename)
431444
{
432-
int lobj_fd;
433-
char buf[BUFSIZE];
434-
int nbytes, tmp;
435-
int fd;
445+
int lobj_fd;
446+
char buf[BUFSIZE];
447+
int nbytes,
448+
tmp;
449+
int fd;
436450

437451
/*
438-
* create an inversion "object"
452+
* create an inversion &quot;object&quot;
439453
*/
440454
lobj_fd = lo_open(conn, lobjId, INV_READ);
441-
if (lobj_fd &lt; 0) {
442-
fprintf(stderr,"can't open large object %d\n",
443-
lobjId);
455+
if (lobj_fd &lt; 0)
456+
{
457+
fprintf(stderr, &quot;can't open large object %d\n&quot;,
458+
lobjId);
444459
}
445460

446461
/*
447462
* open the file to be written to
448463
*/
449-
fd = open(filename, O_CREAT|O_WRONLY, 0666);
450-
if (fd &lt; 0) { /* error */
451-
fprintf(stderr, "can't open unix file %s\n",
452-
filename);
464+
fd = open(filename, O_CREAT | O_WRONLY, 0666);
465+
if (fd &lt; 0)
466+
{ /* error */
467+
fprintf(stderr, &quot;can't open unix file %s\n&quot;,
468+
filename);
453469
}
454470

455471
/*
456472
* read in from the Unix file and write to the inversion file
457473
*/
458-
while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) &gt; 0) {
459-
tmp = write(fd, buf, nbytes);
460-
if (tmp &lt; nbytes) {
461-
fprintf(stderr,"error while writing %s\n",
462-
filename);
463-
}
474+
while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) &gt; 0)
475+
{
476+
tmp = write(fd, buf, nbytes);
477+
if (tmp &lt; nbytes)
478+
{
479+
fprintf(stderr, &quot;error while writing %s\n&quot;,
480+
filename);
481+
}
464482
}
465483

466484
(void) lo_close(conn, lobj_fd);
@@ -470,25 +488,27 @@ void exportFile(PGconn *conn, Oid lobjId, char *filename)
470488
}
471489

472490
void
473-
exit_nicely(PGconn* conn)
491+
exit_nicely(PGconn *conn)
474492
{
475-
PQfinish(conn);
476-
exit(1);
493+
PQfinish(conn);
494+
exit(1);
477495
}
478496

479497
int
480498
main(int argc, char **argv)
481499
{
482-
char *in_filename, *out_filename;
483-
char *database;
484-
Oid lobjOid;
485-
PGconn *conn;
486-
PGresult *res;
487-
488-
if (argc != 4) {
489-
fprintf(stderr, "Usage: %s database_name in_filename out_filename\n",
490-
argv[0]);
491-
exit(1);
500+
char *in_filename,
501+
*out_filename;
502+
char *database;
503+
Oid lobjOid;
504+
PGconn *conn;
505+
PGresult *res;
506+
507+
if (argc != 4)
508+
{
509+
fprintf(stderr, &quot;Usage: %s database_name in_filename out_filename\n&quot;,
510+
argv[0]);
511+
exit(1);
492512
}
493513

494514
database = argv[1];
@@ -501,33 +521,34 @@ main(int argc, char **argv)
501521
conn = PQsetdb(NULL, NULL, NULL, NULL, database);
502522

503523
/* check to see that the backend connection was successfully made */
504-
if (PQstatus(conn) == CONNECTION_BAD) {
505-
fprintf(stderr,"Connection to database '%s' failed.\n", database);
506-
fprintf(stderr,"%s",PQerrorMessage(conn));
507-
exit_nicely(conn);
524+
if (PQstatus(conn) == CONNECTION_BAD)
525+
{
526+
fprintf(stderr, &quot;Connection to database '%s' failed.\n&quot;, database);
527+
fprintf(stderr, &quot;%s&quot;, PQerrorMessage(conn));
528+
exit_nicely(conn);
508529
}
509530

510-
res = PQexec(conn, "begin");
531+
res = PQexec(conn, &quot;begin&quot;);
511532
PQclear(res);
512533

513-
printf("importing file %s\n", in_filename);
534+
printf(&quot;importing file %s\n&quot;, in_filename);
514535
/* lobjOid = importFile(conn, in_filename); */
515536
lobjOid = lo_import(conn, in_filename);
516537
/*
517-
printf("as large object %d.\n", lobjOid);
538+
printf(&quot;as large object %d.\n&quot;, lobjOid);
518539

519-
printf("picking out bytes 1000-2000 of the large object\n");
540+
printf(&quot;picking out bytes 1000-2000 of the large object\n&quot;);
520541
pickout(conn, lobjOid, 1000, 1000);
521542

522-
printf("overwriting bytes 1000-2000 of the large object with X's\n");
543+
printf(&quot;overwriting bytes 1000-2000 of the large object with X's\n&quot;);
523544
overwrite(conn, lobjOid, 1000, 1000);
524545
*/
525546

526-
printf("exporting large object to file %s\n", out_filename);
547+
printf(&quot;exporting large object to file %s\n&quot;, out_filename);
527548
/* exportFile(conn, lobjOid, out_filename); */
528-
lo_export(conn, lobjOid,out_filename);
549+
lo_export(conn, lobjOid, out_filename);
529550

530-
res = PQexec(conn, "end");
551+
res = PQexec(conn, &quot;end&quot;);
531552
PQclear(res);
532553
PQfinish(conn);
533554
exit(0);

0 commit comments

Comments
 (0)