From dd09b151ee6e70a5f7eafbd55a2e41f2c463357e Mon Sep 17 00:00:00 2001
From: Sivirilova Maria <m.sivirilova@ftdata.ru>
Date: Wed, 19 Aug 2026 11:59:55 +0700
Subject: [PATCH] Fix heap-buffer-overflow in PGTYPEStimestamp_defmt_scan()

When parsing format tokens '%D', '%r', '%R', or '%T', the function
allocated memory for the temporary buffer based on the length of the
remaining input string (pstr). However, it subsequently appended the
remaining format string (pfmt) to that buffer via strcat().

If the tail of the format string happened to be longer than the remaining
input string, a heap-buffer-overflow occurred.

Fix this by calculating the required buffer size using the length of
the format string (pfmt) instead of the input string (pstr).

Author: Maria Sivirilova <m.sivirilova@ftdata.ru>
Co-authored-by: Kanatbek Kanybekov <k.kanybekov@ftdata.ru>
---
 src/interfaces/ecpg/pgtypeslib/dt_common.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/interfaces/ecpg/pgtypeslib/dt_common.c b/src/interfaces/ecpg/pgtypeslib/dt_common.c
index f0889dddaf9..6d58dee7890 100644
--- a/src/interfaces/ecpg/pgtypeslib/dt_common.c
+++ b/src/interfaces/ecpg/pgtypeslib/dt_common.c
@@ -2658,7 +2658,7 @@ PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp * d,
 				 * find the end of the substitution
 				 */
 				pfmt++;
-				tmp = pgtypes_alloc(strlen("%m/%d/%y") + strlen(pstr) + 1);
+				tmp = pgtypes_alloc(strlen("%m/%d/%y") + strlen(pfmt) + 1);
 				if (!tmp)
 					return 1;
 				strcpy(tmp, "%m/%d/%y");
@@ -2785,7 +2785,7 @@ PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp * d,
 				break;
 			case 'r':
 				pfmt++;
-				tmp = pgtypes_alloc(strlen("%I:%M:%S %p") + strlen(pstr) + 1);
+				tmp = pgtypes_alloc(strlen("%I:%M:%S %p") + strlen(pfmt) + 1);
 				if (!tmp)
 					return 1;
 				strcpy(tmp, "%I:%M:%S %p");
@@ -2795,7 +2795,7 @@ PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp * d,
 				return err;
 			case 'R':
 				pfmt++;
-				tmp = pgtypes_alloc(strlen("%H:%M") + strlen(pstr) + 1);
+				tmp = pgtypes_alloc(strlen("%H:%M") + strlen(pfmt) + 1);
 				if (!tmp)
 					return 1;
 				strcpy(tmp, "%H:%M");
@@ -2842,7 +2842,7 @@ PGTYPEStimestamp_defmt_scan(char **str, char *fmt, timestamp * d,
 				break;
 			case 'T':
 				pfmt++;
-				tmp = pgtypes_alloc(strlen("%H:%M:%S") + strlen(pstr) + 1);
+				tmp = pgtypes_alloc(strlen("%H:%M:%S") + strlen(pfmt) + 1);
 				if (!tmp)
 					return 1;
 				strcpy(tmp, "%H:%M:%S");
-- 
GitLab

