From 11c1f38413415f582c0596ff745e4cbfb1848126 Mon Sep 17 00:00:00 2001 From: jian he Date: Sun, 26 Jan 2025 22:36:28 +0800 Subject: [PATCH v11 1/1] refactoring ReadOneStatement escape single quote and double quote for ReadOneStatement. the following are some tests to prove it accurate. create role y; comment on role y is $$;"'$$; create role "'"; create role "'';"; create role "';;;';"; create role z; comment on role z is $$"";';$$; create role "; '; ; "; create role ";"; comment on role ";" is $$;"';',",' $$; comment on role ";" is $$;"';',",' $$; create role " "; comment on role z is $$;"';',",'';;'"";$$; --- src/bin/pg_dump/pg_restore.c | 49 ++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/src/bin/pg_dump/pg_restore.c b/src/bin/pg_dump/pg_restore.c index 79f61395ae..65029ecb76 100644 --- a/src/bin/pg_dump/pg_restore.c +++ b/src/bin/pg_dump/pg_restore.c @@ -764,6 +764,10 @@ static int ReadOneStatement(StringInfo inBuf, FILE *pfile) { int c; /* character read from getc() */ + int m; + + StringInfoData q; + initStringInfo(&q); resetStringInfo(inBuf); @@ -772,16 +776,44 @@ ReadOneStatement(StringInfo inBuf, FILE *pfile) */ while ((c = fgetc(pfile)) != EOF) { - appendStringInfoChar(inBuf, (char) c); + if (c != '\'' && c != '"' && c != '\n' && c != ';') + { + appendStringInfoChar(inBuf, (char) c); + while ((c = fgetc(pfile)) != EOF) + { + if (c != '\'' && c != '"' && c != ';' && c != '\n') + appendStringInfoChar(inBuf, (char) c); + else + break; + } + } + + if (c == '\'' || c == '"') + { + appendStringInfoChar(&q, (char) c); + m = c; + + while ((c = fgetc(pfile)) != EOF) + { + appendStringInfoChar(&q, (char) c); + + if( c == m) + { + appendStringInfoString(inBuf, q.data); + resetStringInfo(&q); + break; + } + } + } + + if (c == ';') + { + appendStringInfoChar(inBuf, (char) c); + break; + } if (c == '\n') - { - if(inBuf->len > 1 && - inBuf->data[inBuf->len - 2] == ';') - break; - else - continue; - } + appendStringInfoChar(inBuf, (char) c); } /* No input before EOF signal means time to quit. */ @@ -1113,6 +1145,7 @@ execute_global_sql_commands(PGconn *conn, const char *dumpdirpath, const char *o /* Process file till EOF and execute sql statements */ while (ReadOneStatement(&sqlstatement, pfile) != EOF) { + pg_log_info("executing %s", sqlstatement.data); result = PQexec(conn, sqlstatement.data); switch (PQresultStatus(result)) -- 2.34.1