0001-snapmgr-replace-sscanf-with-strtol-strtoul-in-snapsh.patch

application/x-patch

Filename: 0001-snapmgr-replace-sscanf-with-strtol-strtoul-in-snapsh.patch
Type: application/x-patch
Part: 0
Message: Cleanup: Replace sscanf with strtol/strtoul in snapmgr

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: format-patch
Series: patch 0001
Subject: snapmgr: replace sscanf with strtol/strtoul in snapshot parse helpers
File+
src/backend/utils/time/snapmgr.c 35 10
From 9869b9f19775de7d13f1bada5db5d8f14bf20859 Mon Sep 17 00:00:00 2001
From: Amul Sul <sulamul@gmail.com>
Date: Mon, 20 Apr 2026 10:21:28 +0530
Subject: [PATCH] snapmgr: replace sscanf with strtol/strtoul in snapshot parse
 helpers

parseIntFromText, parseXidFromText, and parseVxidFromText used sscanf
to convert digit strings to integers.  Replace with strtol/strtoul,
which provide explicit overflow detection and advance the end-pointer
directly, avoiding a redundant strchr scan over the already-parsed
digits.
---
 src/backend/utils/time/snapmgr.c | 45 +++++++++++++++++++++++++-------
 1 file changed, 35 insertions(+), 10 deletions(-)

diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c
index 10fe18df2e7..20b8421b881 100644
--- a/src/backend/utils/time/snapmgr.c
+++ b/src/backend/utils/time/snapmgr.c
@@ -1308,24 +1308,27 @@ parseIntFromText(const char *prefix, char **s, const char *filename)
 {
 	char	   *ptr = *s;
 	int			prefixlen = strlen(prefix);
-	int			val;
+	long		val;
+	char	   *endptr;
 
 	if (strncmp(ptr, prefix, prefixlen) != 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 				 errmsg("invalid snapshot data in file \"%s\"", filename)));
 	ptr += prefixlen;
-	if (sscanf(ptr, "%d", &val) != 1)
+	errno = 0;
+	val = strtol(ptr, &endptr, 10);
+	if (endptr == ptr || errno != 0 || val < INT_MIN || val > INT_MAX)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 				 errmsg("invalid snapshot data in file \"%s\"", filename)));
-	ptr = strchr(ptr, '\n');
+	ptr = strchr(endptr, '\n');
 	if (!ptr)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 				 errmsg("invalid snapshot data in file \"%s\"", filename)));
 	*s = ptr + 1;
-	return val;
+	return (int) val;
 }
 
 static TransactionId
@@ -1333,24 +1336,27 @@ parseXidFromText(const char *prefix, char **s, const char *filename)
 {
 	char	   *ptr = *s;
 	int			prefixlen = strlen(prefix);
-	TransactionId val;
+	unsigned long val;
+	char	   *endptr;
 
 	if (strncmp(ptr, prefix, prefixlen) != 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 				 errmsg("invalid snapshot data in file \"%s\"", filename)));
 	ptr += prefixlen;
-	if (sscanf(ptr, "%u", &val) != 1)
+	errno = 0;
+	val = strtoul(ptr, &endptr, 10);
+	if (endptr == ptr || errno != 0 || val > UINT_MAX)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 				 errmsg("invalid snapshot data in file \"%s\"", filename)));
-	ptr = strchr(ptr, '\n');
+	ptr = strchr(endptr, '\n');
 	if (!ptr)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 				 errmsg("invalid snapshot data in file \"%s\"", filename)));
 	*s = ptr + 1;
-	return val;
+	return (TransactionId) val;
 }
 
 static void
@@ -1359,17 +1365,36 @@ parseVxidFromText(const char *prefix, char **s, const char *filename,
 {
 	char	   *ptr = *s;
 	int			prefixlen = strlen(prefix);
+	long		lval;
+	unsigned long ulval;
+	char	   *endptr;
 
 	if (strncmp(ptr, prefix, prefixlen) != 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 				 errmsg("invalid snapshot data in file \"%s\"", filename)));
 	ptr += prefixlen;
-	if (sscanf(ptr, "%d/%u", &vxid->procNumber, &vxid->localTransactionId) != 2)
+
+	/* Parse procNumber (the signed integer before '/') */
+	errno = 0;
+	lval = strtol(ptr, &endptr, 10);
+	if (endptr == ptr || errno != 0 || lval < INT_MIN || lval > INT_MAX ||
+		*endptr != '/')
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 				 errmsg("invalid snapshot data in file \"%s\"", filename)));
-	ptr = strchr(ptr, '\n');
+	vxid->procNumber = (ProcNumber) lval;
+	ptr = endptr + 1;			/* skip the '/' separator */
+
+	/* Parse localTransactionId (the unsigned integer after '/') */
+	errno = 0;
+	ulval = strtoul(ptr, &endptr, 10);
+	if (endptr == ptr || errno != 0 || ulval > UINT_MAX)
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
+				 errmsg("invalid snapshot data in file \"%s\"", filename)));
+	vxid->localTransactionId = (LocalTransactionId) ulval;
+	ptr = strchr(endptr, '\n');
 	if (!ptr)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
-- 
2.47.1