I found a couple of places where a pgoff_t value, typically a signed
64-bit integer, is cast to a type with a smaller range. I noticed this
specifically in error messages, so it's mostly cosmetic. Also, files
with a size where this would matter are not expected in many places, but
I suspect that the case in basebackup_server.c in the attached patch can
actually happen.
The fix is to use the %lld print format and a cast to long long int,
which is the style already in most places.
In passing, I also converted a few places that used %llu to print
pgoff_t to also use %lld instead. This is mostly for consistency, but
it also feels more robust in case a negative value ever sneaks in.
From abdb70a05f0d5b24511a5b915426fb4c1d7000d4 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Fri, 12 Jun 2026 08:53:24 +0200
Subject: [PATCH 1/2] Don't cast pgoff_t to possibly 32-bit types for output
pgoff_t is most likely a 64-bit integer, so casting it to a 32-bit
type for output could lose data.
In one case, the 32-bit size is baked into the protocol, so here we
just add an assertion and document this discrepancy.
---
src/backend/backup/basebackup_server.c | 8 ++++----
src/backend/backup/walsummary.c | 4 ++--
src/backend/replication/walsender.c | 2 ++
src/backend/storage/file/fd.c | 4 ++--
4 files changed, 10 insertions(+), 8 deletions(-)
diff --git a/src/backend/backup/basebackup_server.c
b/src/backend/backup/basebackup_server.c
index 0d44a148f01..3d44bf71d19 100644
--- a/src/backend/backup/basebackup_server.c
+++ b/src/backend/backup/basebackup_server.c
@@ -176,9 +176,9 @@ bbsink_server_archive_contents(bbsink *sink, size_t len)
/* short write: complain appropriately */
ereport(ERROR,
(errcode(ERRCODE_DISK_FULL),
- errmsg("could not write file \"%s\": wrote
only %d of %zu bytes at offset %u",
+ errmsg("could not write file \"%s\": wrote
only %d of %zu bytes at offset %lld",
FilePathName(mysink->file),
- nbytes, len, (unsigned)
mysink->filepos),
+ nbytes, len, (long long)
mysink->filepos),
errhint("Check free disk space.")));
}
@@ -269,9 +269,9 @@ bbsink_server_manifest_contents(bbsink *sink, size_t len)
/* short write: complain appropriately */
ereport(ERROR,
(errcode(ERRCODE_DISK_FULL),
- errmsg("could not write file \"%s\": wrote
only %d of %zu bytes at offset %u",
+ errmsg("could not write file \"%s\": wrote
only %d of %zu bytes at offset %lld",
FilePathName(mysink->file),
- nbytes, len, (unsigned)
mysink->filepos),
+ nbytes, len, (long long)
mysink->filepos),
errhint("Check free disk space.")));
}
diff --git a/src/backend/backup/walsummary.c b/src/backend/backup/walsummary.c
index 0cdc86af30b..48b7bd8c521 100644
--- a/src/backend/backup/walsummary.c
+++ b/src/backend/backup/walsummary.c
@@ -306,9 +306,9 @@ WriteWalSummary(void *wal_summary_io, void *data, int
length)
if (nbytes != length)
ereport(ERROR,
(errcode_for_file_access(),
- errmsg("could not write file \"%s\": wrote
only %d of %d bytes at offset %u",
+ errmsg("could not write file \"%s\": wrote
only %d of %d bytes at offset %lld",
FilePathName(io->file), nbytes,
- length, (unsigned) io->filepos),
+ length, (long long)
io->filepos),
errhint("Check free disk space.")));
io->filepos += nbytes;
diff --git a/src/backend/replication/walsender.c
b/src/backend/replication/walsender.c
index c931d9b4fa8..de8c9940877 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -661,6 +661,8 @@ SendTimeLineHistory(TimeLineHistoryCmd *cmd)
(errcode_for_file_access(),
errmsg("could not seek to beginning of file
\"%s\": %m", path)));
+ /* XXX might truncate histfilelen */
+ Assert(histfilelen <= UINT32_MAX);
pq_sendint32(&buf, histfilelen); /* col2 len */
bytesleft = histfilelen;
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 4cf4717f764..b8a66b3b475 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -1521,8 +1521,8 @@ ReportTemporaryFileUsage(const char *path, pgoff_t size)
{
if ((size / 1024) >= log_temp_files)
ereport(LOG,
- (errmsg("temporary file: path \"%s\",
size %lu",
- path, (unsigned long)
size)));
+ (errmsg("temporary file: path \"%s\",
size %lld",
+ path, (long long)
size)));
}
}
--
2.54.0
From 51214bcaf25a3b647932ce93bdc0308e93543431 Mon Sep 17 00:00:00 2001
From: Peter Eisentraut <[email protected]>
Date: Fri, 12 Jun 2026 10:12:08 +0200
Subject: [PATCH 2/2] Print off_t/pgoff_t consistently as %lld
This was the dominant style already, but some places used %llu
instead. Since off_t/pgoff_t are signed types, using %lld seems a
better match, and it might handle obscure error conditions with
negative values better.
---
src/bin/pg_combinebackup/reconstruct.c | 10 +++++-----
src/bin/pg_dump/pg_backup_tar.c | 8 ++++----
src/bin/pg_verifybackup/astreamer_verify.c | 4 ++--
src/bin/pg_verifybackup/pg_verifybackup.c | 6 +++---
4 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/src/bin/pg_combinebackup/reconstruct.c
b/src/bin/pg_combinebackup/reconstruct.c
index 0541e6dacab..73b38236481 100644
--- a/src/bin/pg_combinebackup/reconstruct.c
+++ b/src/bin/pg_combinebackup/reconstruct.c
@@ -421,10 +421,10 @@ debug_reconstruction(int n_source, rfile **sources, bool
dry_run)
if (fstat(s->fd, &sb) < 0)
pg_fatal("could not stat file \"%s\": %m",
s->filename);
if (sb.st_size < s->highest_offset_read)
- pg_fatal("file \"%s\" is too short: expected
%llu, found %llu",
+ pg_fatal("file \"%s\" is too short: expected
%lld, found %lld",
s->filename,
- (unsigned long long)
s->highest_offset_read,
- (unsigned long long)
sb.st_size);
+ (long long)
s->highest_offset_read,
+ (long long) sb.st_size);
}
}
}
@@ -785,7 +785,7 @@ read_block(const rfile *s, off_t off, uint8 *buffer)
if (rb < 0)
pg_fatal("could not read from file \"%s\": %m",
s->filename);
else
- pg_fatal("could not read from file \"%s\", offset %llu:
read %d of %d",
- s->filename, (unsigned long long) off,
rb, BLCKSZ);
+ pg_fatal("could not read from file \"%s\", offset %lld:
read %d of %d",
+ s->filename, (long long) off, rb,
BLCKSZ);
}
}
diff --git a/src/bin/pg_dump/pg_backup_tar.c b/src/bin/pg_dump/pg_backup_tar.c
index 55b1e4e85d0..1f5d55d0365 100644
--- a/src/bin/pg_dump/pg_backup_tar.c
+++ b/src/bin/pg_dump/pg_backup_tar.c
@@ -1169,12 +1169,12 @@ _tarGetHeader(ArchiveHandle *AH, TAR_MEMBER *th)
len = read_tar_number(&h[TAR_OFFSET_SIZE], 12);
- pg_log_debug("TOC Entry %s at %llu (length %llu, checksum %d)",
- tag, (unsigned long long) hPos, (unsigned long
long) len, sum);
+ pg_log_debug("TOC Entry %s at %lld (length %lld, checksum %d)",
+ tag, (long long) hPos, (long long) len, sum);
if (chk != sum)
- pg_fatal("corrupt tar header found in %s (expected %d, computed
%d) file position %llu",
- tag, sum, chk, (unsigned long long)
ftello(ctx->tarFH));
+ pg_fatal("corrupt tar header found in %s (expected %d, computed
%d) file position %lld",
+ tag, sum, chk, (long long) ftello(ctx->tarFH));
th->targetFile = pg_strdup(tag);
th->fileLen = len;
diff --git a/src/bin/pg_verifybackup/astreamer_verify.c
b/src/bin/pg_verifybackup/astreamer_verify.c
index 99bd69ce7c9..2578765b0ca 100644
--- a/src/bin/pg_verifybackup/astreamer_verify.c
+++ b/src/bin/pg_verifybackup/astreamer_verify.c
@@ -208,9 +208,9 @@ member_verify_header(astreamer *streamer, astreamer_member
*member)
if (m->size != member->size)
{
report_backup_error(mystreamer->context,
- "file \"%s\" has size
%llu in archive \"%s\" but size %" PRIu64 " in the manifest",
+ "file \"%s\" has size
%lld in archive \"%s\" but size %" PRIu64 " in the manifest",
member->pathname,
- (unsigned long long)
member->size,
+ (long long)
member->size,
mystreamer->archive_name,
m->size);
m->bad = true;
diff --git a/src/bin/pg_verifybackup/pg_verifybackup.c
b/src/bin/pg_verifybackup/pg_verifybackup.c
index bd4fe635c6f..5c63bea14c7 100644
--- a/src/bin/pg_verifybackup/pg_verifybackup.c
+++ b/src/bin/pg_verifybackup/pg_verifybackup.c
@@ -735,9 +735,9 @@ verify_plain_backup_file(verifier_context *context, char
*relpath,
if (m->size != sb.st_size)
{
report_backup_error(context,
- "\"%s\" has size %llu
on disk but size %llu in the manifest",
- relpath, (unsigned long
long) sb.st_size,
- (unsigned long long)
m->size);
+ "\"%s\" has size %lld
on disk but size %" PRIu64 " in the manifest",
+ relpath, (long long)
sb.st_size,
+ m->size);
m->bad = true;
}
--
2.54.0