From 4b517af92da992abcaa04170a577887e11e29302 Mon Sep 17 00:00:00 2001 From: Kyotaro Horiguchi 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