From 4b517af92da992abcaa04170a577887e11e29302 Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
Date: Mon, 10 Apr 2023 16:39:44 +0900
Subject: [PATCH 2/2] Fix sqlda handling in ORACLE compat code

When compiled with -C ORACLE, ecpg_get_data incorrectly stores the
null terminator byte to str[-1] when varcharsize is zero. Fix this by
assuming the callers provided a exact-fit storage, as they actually
do, on which no padding or truncation is required.
---
 src/interfaces/ecpg/ecpglib/data.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)

diff --git a/src/interfaces/ecpg/ecpglib/data.c b/src/interfaces/ecpg/ecpglib/data.c
index bf9b313a11..3e47724b93 100644
--- a/src/interfaces/ecpg/ecpglib/data.c
+++ b/src/interfaces/ecpg/ecpglib/data.c
@@ -578,7 +578,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 						if (varcharsize == 0 && offset == sizeof(char *))
 							str = *(char **) str;
 
-						if (varcharsize == 0 || varcharsize > size)
+						if (varcharsize > size)
 						{
 							/*
 							 * compatibility mode, blank pad and null
@@ -638,16 +638,25 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
 						}
 						else
 						{
-							strncpy(str, pval, varcharsize);
+							int charsize = varcharsize;
+
+							/*
+							 * assume the caller provided exact-fit storage
+							 * when varcharsize is zero
+							 */
+							if (varcharsize == 0)
+								charsize = size + 1;
+
+							strncpy(str, pval, charsize);
 
 							/* compatibility mode, null terminate char array */
-							if (ORACLE_MODE(compat) && (varcharsize - 1) < size)
+							if (ORACLE_MODE(compat) && (charsize - 1) < size)
 							{
 								if (type == ECPGt_char || type == ECPGt_unsigned_char)
-									str[varcharsize - 1] = '\0';
+									str[charsize - 1] = '\0';
 							}
 
-							if (varcharsize < size || (ORACLE_MODE(compat) && (varcharsize - 1) < size))
+							if (charsize < size || (ORACLE_MODE(compat) && (charsize - 1) < size))
 							{
 								/* truncation */
 								switch (ind_type)
-- 
2.31.1

