Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf180290

Browse files
committed
ecpg: Fix handling of strings in ORACLE compat code with SQLDA
When compiled with -C ORACLE, ecpg_get_data() had a one-off issue whereit would incorrectly store the null terminator byte to str[-1] whenvarcharsize is 0, which is something that can happen when using SQLDA.This would eat 1 byte from the previous field stored, corrupting theresults generated.All the callers of ecpg_get_data() estimate and allocate enough storagefor the data received, and the fix of this commit relies on thisassumption. Note that this maps to the case where no padding ortruncation is required.This issue has been introduced by3b7ab43 with the Oracle compatibilityoption, so backpatch down to v11.Author: Kyotaro HoriguchiDiscussion:https://postgr.es/m/20230410.173500.440060475837236886.horikyota.ntt@gmail.comBackpatch-through: 11
1 parenteef231e commitf180290

File tree

5 files changed

+310
-127
lines changed

5 files changed

+310
-127
lines changed

‎src/interfaces/ecpg/ecpglib/data.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -578,7 +578,7 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
578578
if (varcharsize==0&&offset==sizeof(char*))
579579
str=*(char**)str;
580580

581-
if (varcharsize==0||varcharsize>size)
581+
if (varcharsize>size)
582582
{
583583
/*
584584
* compatibility mode, blank pad and null
@@ -638,16 +638,25 @@ ecpg_get_data(const PGresult *results, int act_tuple, int act_field, int lineno,
638638
}
639639
else
640640
{
641-
strncpy(str,pval,varcharsize);
641+
intcharsize=varcharsize;
642+
643+
/*
644+
* assume that the caller provided storage exactly
645+
* fit when varcharsize is zero.
646+
*/
647+
if (varcharsize==0)
648+
charsize=size+1;
649+
650+
strncpy(str,pval,charsize);
642651

643652
/* compatibility mode, null terminate char array */
644-
if (ORACLE_MODE(compat)&& (varcharsize-1)<size)
653+
if (ORACLE_MODE(compat)&& (charsize-1)<size)
645654
{
646655
if (type==ECPGt_char||type==ECPGt_unsigned_char)
647-
str[varcharsize-1]='\0';
656+
str[charsize-1]='\0';
648657
}
649658

650-
if (varcharsize<size|| (ORACLE_MODE(compat)&& (varcharsize-1)<size))
659+
if (charsize<size|| (ORACLE_MODE(compat)&& (charsize-1)<size))
651660
{
652661
/* truncation */
653662
switch (ind_type)

‎src/interfaces/ecpg/test/compat_oracle/char_array.pgc

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22
#include <stdlib.h>
33
#include <string.h>
44

5+
#include <pgtypes_numeric.h>
6+
7+
EXEC SQL INCLUDE sqlda.h;
8+
59
EXEC SQL INCLUDE ../regression;
610

711
static void warn(void)
@@ -20,6 +24,8 @@ int main() {
2024

2125
const char *ppppp = "XXXXX";
2226
int loopcount;
27+
sqlda_t *sqlda = NULL;
28+
2329
EXEC SQL BEGIN DECLARE SECTION;
2430
char shortstr[5];
2531
char bigstr[11];
@@ -53,11 +59,34 @@ int main() {
5359

5460
EXEC SQL CLOSE C;
5561
EXEC SQL DROP TABLE strdbase;
62+
EXEC SQL COMMIT WORK;
5663

57-
printf("\nGOOD-BYE!!\n\n");
64+
/* SQLDA handling */
65+
EXEC SQL WHENEVER SQLWARNING SQLPRINT;
66+
EXEC SQL WHENEVER NOT FOUND STOP;
67+
EXEC SQL PREPARE stmt1 FROM "SELECT 123::numeric(3,0), 't'::varchar(2)";
68+
EXEC SQL DECLARE cur1 CURSOR FOR stmt1;
69+
EXEC SQL OPEN cur1;
70+
EXEC SQL FETCH NEXT FROM cur1 INTO DESCRIPTOR sqlda;
71+
72+
printf("\n-----------------\ntype : data\n");
73+
for (int i = 0 ; i < sqlda->sqld ; i++)
74+
{
75+
sqlvar_t v = sqlda->sqlvar[i];
76+
char *sqldata = v.sqldata;
77+
78+
if (v.sqltype == ECPGt_numeric)
79+
sqldata =
80+
PGTYPESnumeric_to_asc((numeric*) sqlda->sqlvar[i].sqldata, -1);
81+
82+
printf("%-8s: \"%s\"\n", v.sqlname.data, sqldata);
83+
}
5884

85+
EXEC SQL CLOSE cur1;
5986
EXEC SQL COMMIT WORK;
6087

88+
printf("\nGOOD-BYE!!\n\n");
89+
6190
EXEC SQL DISCONNECT ALL;
6291

6392
return 0;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp