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

Commit78e957d

Browse files
committed
Fix pg_restore's direct-to-database mode for standard_conforming_strings.
pg_backup_db.c contained a mini SQL lexer with which it tried to identifyboundaries between SQL commands, but that code was not designed to copewith standard_conforming_strings, and would get the wrong answer if abackslash immediately precedes a closing single quote in such a string,as per report from Julian Mehnle. The bug only affects direct-to-databaserestores from archive files made with standard_conforming_strings = on.Rather than complicating the code some more to try to fix that, let's justrip it all out. The only reason it was needed was to cope with COPY dataembedded into ordinary archive entries, which was a layout that was usedonly for about the first three weeks of the archive format's existence,and never in any production release of pg_dump. Instead, just rely on thearchive file layout to tell us whether we're printing COPY data or not.This bug represents a data corruption hazard in all releases in whichstandard_conforming_strings can be turned on, ie 8.2 and later, soback-patch to all supported branches.
1 parentbc9d2e7 commit78e957d

File tree

4 files changed

+67
-386
lines changed

4 files changed

+67
-386
lines changed

‎src/bin/pg_dump/pg_backup_archiver.c

Lines changed: 18 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ static TocEntry *getTocEntryByDumpId(ArchiveHandle *AH, DumpId id);
109109
staticvoid_moveBefore(ArchiveHandle*AH,TocEntry*pos,TocEntry*te);
110110
staticint_discoverArchiveFormat(ArchiveHandle*AH);
111111

112+
staticintRestoringToDB(ArchiveHandle*AH);
112113
staticvoiddump_lo_buf(ArchiveHandle*AH);
113114
staticvoid_write_msg(constchar*modulename,constchar*fmt,va_listap);
114115
staticvoid_die_horribly(ArchiveHandle*AH,constchar*modulename,constchar*fmt,va_listap);
@@ -579,13 +580,7 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te,
579580
}
580581

581582
/*
582-
* If we have a copy statement, use it. As of V1.3, these
583-
* are separate to allow easy import from withing a
584-
* database connection. Pre 1.3 archives can not use DB
585-
* connections and are sent to output only.
586-
*
587-
* For V1.3+, the table data MUST have a copy statement so
588-
* that we can go into appropriate mode with libpq.
583+
* If we have a copy statement, use it.
589584
*/
590585
if (te->copyStmt&&strlen(te->copyStmt)>0)
591586
{
@@ -595,7 +590,15 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te,
595590

596591
(*AH->PrintTocDataPtr) (AH,te,ropt);
597592

598-
AH->writingCopyData= false;
593+
/*
594+
* Terminate COPY if needed.
595+
*/
596+
if (AH->writingCopyData)
597+
{
598+
if (RestoringToDB(AH))
599+
EndDBCopyMode(AH,te);
600+
AH->writingCopyData= false;
601+
}
599602

600603
/* close out the transaction started above */
601604
if (is_parallel&&te->created)
@@ -1233,17 +1236,13 @@ ahprintf(ArchiveHandle *AH, const char *fmt,...)
12331236
{
12341237
char*p=NULL;
12351238
va_listap;
1236-
intbSize=strlen(fmt)+256;/*Should be enough */
1239+
intbSize=strlen(fmt)+256;/*Usually enough */
12371240
intcnt=-1;
12381241

12391242
/*
12401243
* This is paranoid: deal with the possibility that vsnprintf is willing
1241-
* to ignore trailing null
1242-
*/
1243-
1244-
/*
1245-
* or returns > 0 even if string does not fit. It may be the case that it
1246-
* returns cnt = bufsize
1244+
* to ignore trailing null or returns > 0 even if string does not fit.
1245+
* It may be the case that it returns cnt = bufsize.
12471246
*/
12481247
while (cnt<0||cnt >= (bSize-1))
12491248
{
@@ -1325,7 +1324,7 @@ dump_lo_buf(ArchiveHandle *AH)
13251324

13261325

13271326
/*
1328-
*Write buffer to the output file (usually stdout). This isuser for
1327+
*Write buffer to the output file (usually stdout). This isused for
13291328
*outputting 'restore' scripts etc. It is even possible for an archive
13301329
*format to create a custom output routine to 'fake' a restore if it
13311330
*wants to generate a script (see TAR output).
@@ -1377,7 +1376,7 @@ ahwrite(const void *ptr, size_t size, size_t nmemb, ArchiveHandle *AH)
13771376
* connected then send it to the DB.
13781377
*/
13791378
if (RestoringToDB(AH))
1380-
returnExecuteSqlCommandBuf(AH, (void*)ptr,size*nmemb);/* Always 1, currently */
1379+
returnExecuteSqlCommandBuf(AH, (constchar*)ptr,size*nmemb);
13811380
else
13821381
{
13831382
res=fwrite((void*)ptr,size,nmemb,AH->OF);
@@ -1934,9 +1933,6 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt,
19341933
AH->mode=mode;
19351934
AH->compression=compression;
19361935

1937-
AH->pgCopyBuf=createPQExpBuffer();
1938-
AH->sqlBuf=createPQExpBuffer();
1939-
19401936
/* Open stdout with no compression for AH output handle */
19411937
AH->gzOut=0;
19421938
AH->OF=stdout;
@@ -4134,10 +4130,7 @@ CloneArchive(ArchiveHandle *AH)
41344130
die_horribly(AH,modulename,"out of memory\n");
41354131
memcpy(clone,AH,sizeof(ArchiveHandle));
41364132

4137-
/* Handle format-independent fields */
4138-
clone->pgCopyBuf=createPQExpBuffer();
4139-
clone->sqlBuf=createPQExpBuffer();
4140-
clone->sqlparse.tagBuf=NULL;
4133+
/* Handle format-independent fields ... none at the moment */
41414134

41424135
/* The clone will have its own connection, so disregard connection state */
41434136
clone->connection=NULL;
@@ -4170,11 +4163,7 @@ DeCloneArchive(ArchiveHandle *AH)
41704163
/* Clear format-specific state */
41714164
(AH->DeClonePtr) (AH);
41724165

4173-
/* Clear state allocated by CloneArchive */
4174-
destroyPQExpBuffer(AH->pgCopyBuf);
4175-
destroyPQExpBuffer(AH->sqlBuf);
4176-
if (AH->sqlparse.tagBuf)
4177-
destroyPQExpBuffer(AH->sqlparse.tagBuf);
4166+
/* Clear state allocated by CloneArchive ... none at the moment */
41784167

41794168
/* Clear any connection-local state */
41804169
if (AH->currUser)

‎src/bin/pg_dump/pg_backup_archiver.h

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -137,28 +137,6 @@ typedef struct _outputContext
137137
intgzOut;
138138
}OutputContext;
139139

140-
typedefenum
141-
{
142-
SQL_SCAN=0,/* normal */
143-
SQL_IN_SQL_COMMENT,/* -- comment */
144-
SQL_IN_EXT_COMMENT,/* slash-star comment */
145-
SQL_IN_SINGLE_QUOTE,/* '...' literal */
146-
SQL_IN_E_QUOTE,/* E'...' literal */
147-
SQL_IN_DOUBLE_QUOTE,/* "..." identifier */
148-
SQL_IN_DOLLAR_TAG,/* possible dollar-quote starting tag */
149-
SQL_IN_DOLLAR_QUOTE/* body of dollar quote */
150-
}sqlparseState;
151-
152-
typedefstruct
153-
{
154-
sqlparseStatestate;/* see above */
155-
charlastChar;/* preceding char, or '\0' initially */
156-
boolbackSlash;/* next char is backslash quoted? */
157-
intbraceDepth;/* parenthesis nesting depth */
158-
PQExpBuffertagBuf;/* dollar quote tag (NULL if not created) */
159-
intminTagEndPos;/* first possible end position of $-quote */
160-
}sqlparseInfo;
161-
162140
typedefenum
163141
{
164142
STAGE_NONE=0,
@@ -194,9 +172,6 @@ typedef struct _archiveHandle
194172
* Added V1.7 */
195173
ArchiveFormatformat;/* Archive format */
196174

197-
sqlparseInfosqlparse;
198-
PQExpBuffersqlBuf;
199-
200175
time_tcreateDate;/* Date archive created */
201176

202177
/*
@@ -249,8 +224,6 @@ typedef struct _archiveHandle
249224
* required */
250225
boolwritingCopyData;/* True when we are sending COPY data */
251226
boolpgCopyIn;/* Currently in libpq 'COPY IN' mode. */
252-
PQExpBufferpgCopyBuf;/* Left-over data from incomplete lines in
253-
* COPY IN */
254227

255228
intloFd;/* BLOB fd */
256229
intwritingBlob;/* Flag */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp