diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 9ec0be77ca0..25fe4f503b3 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -9995,6 +9995,11 @@ do_pg_backup_start(const char *backupidstr, bool fast, List **tablespaces, errmsg("backup label too long (max %d bytes)", MAXPGPATH))); + if (strpbrk(backupidstr, "\n\r")) + ereport(ERROR, + (errcode(ERRCODE_INVALID_PARAMETER_VALUE), + errmsg("backup label contains a newline or carriage return character"))); + strlcpy(state->name, backupidstr, sizeof(state->name)); /* diff --git a/src/test/recovery/t/020_archive_status.pl b/src/test/recovery/t/020_archive_status.pl index 5bb8aa9ec17..94d49751f7c 100644 --- a/src/test/recovery/t/020_archive_status.pl +++ b/src/test/recovery/t/020_archive_status.pl @@ -260,6 +260,19 @@ $cmdret = $primary->psql( stderr => \$stderr); is($cmdret, 3, "psql fails correctly"); like($stderr, qr/backup label too long/, "pg_backup_start fails gracefully"); + +# Newlines and carriage returns are not allowed in backup labels +foreach my $label ("E'one\\nbackup'", "E'one\\rbackup'") +{ + $primary->psql( + 'postgres', + "SELECT pg_backup_start($label)", + stderr => \$stderr); + like( + $stderr, + qr/backup label contains a newline or carriage return character/, + "pg_backup_start rejects label $label"); +} $primary->safe_psql('postgres', "SELECT pg_backup_start('onebackup'); SELECT pg_backup_stop();"); $primary->safe_psql('postgres', "SELECT pg_backup_start('twobackup')");